func getOwner(ncMeta metav1.ObjectMeta) metav1.OwnerReference {
	owners := ncMeta.GetOwnerReferences()
	if len(owners) == 0 {
		return metav1.OwnerReference{}
	}
	for _, owner := range owners {
		if owner.APIVersion == controlplanev1.GroupVersion.String() &&
			owner.Kind == "NestedControlPlane" {
			return owner
		}
	}
	return metav1.OwnerReference{}
}
getOwner gets the ownerreference of the NestedComponent.
package controllers
import (
	"bytes"
	"context"
	"fmt"
	"io/ioutil"
	"text/template"
	openuri "github.com/utahta/go-openuri"
	"github.com/go-logr/logr"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/kubernetes/scheme"
	ctrlcli "sigs.k8s.io/controller-runtime/pkg/client"
	controlplanev1 "sigs.k8s.io/cluster-api-provider-nested/controlplane/nested/api/v1alpha4"
	addonv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1"
)
func createNestedComponentSts(ctx context.Context,
	cli ctrlcli.Client, ncMeta metav1.ObjectMeta,
	ncSpec controlplanev1.NestedComponentSpec,
	ncKind controlplanev1.ComponentKind,
	controlPlaneName, clusterName, templatePath string, log logr.Logger) error {
	ncSts := &appsv1.StatefulSet{}
	ncSvc := &corev1.Service{}
	or := metav1.NewControllerRef(&ncMeta,
		controlplanev1.GroupVersion.WithKind(string(ncKind)))
	if ncSpec.Version != "" && ncSpec.Channel != "" {
		panic("NOT IMPLEMENT YET")
	}
	log.V(4).Info("The Version and Channel are not set, " +
		"will use the default template.")
	if err := genStatefulSetObject(templatePath, ncMeta, ncSpec, ncKind, controlPlaneName, clusterName, log, ncSts); err != nil {
		return fmt.Errorf("fail to generate the Statefulset object: %v", err)
	}
	if ncKind != controlplanev1.ControllerManager {
		if err := genServiceObject(templatePath, ncMeta, ncSpec, ncKind, controlPlaneName, clusterName, log, ncSvc); err != nil {
			return fmt.Errorf("fail to generate the Service object: %v", err)
		}
		ncSvc.SetOwnerReferences([]metav1.OwnerReference{*or})
		if err := cli.Create(ctx, ncSvc); err != nil {
			return err
		}
		log.Info("successfully create the service for the StatefulSet",
			"component", ncKind)
	}
	ncSts.SetOwnerReferences([]metav1.OwnerReference{*or})
	return cli.Create(ctx, ncSts)
}
func genServiceObject(
	templatePath string,
	ncMeta metav1.ObjectMeta,
	ncSpec controlplanev1.NestedComponentSpec, ncKind controlplanev1.ComponentKind,
	controlPlaneName, clusterName string, log logr.Logger, svc *corev1.Service) error {
	var templateURL string
	if ncSpec.Version == "" && ncSpec.Channel == "" {
		switch ncKind {
		case controlplanev1.APIServer:
			templateURL = templatePath + defaultKASServiceURL
		case controlplanev1.Etcd:
			templateURL = templatePath + defaultEtcdServiceURL
		default:
			panic("Unreachable")
		}
	} else {
		panic("NOT IMPLEMENT YET")
	}
	svcTmpl, err := fetchTemplate(templateURL)
	if err != nil {
		return fmt.Errorf("fail to fetch the default template "+
			"for the %s service: %v", ncKind, err)
	}
	templateCtx := getTemplateArgs(ncMeta, controlPlaneName, clusterName)
	svcStr, err := substituteTemplate(templateCtx, svcTmpl)
	if err != nil {
		return fmt.Errorf("fail to substitute the default template "+
			"for the nestedetcd Service: %v", err)
	}
	if err := yamlToObject([]byte(svcStr), svc); err != nil {
		return fmt.Errorf("fail to convert yaml file to Serivce: %v", err)
	}
	log.Info("deserialize yaml to runtime object(Service)")
	return nil
}
func genStatefulSetObject(
	templatePath string,
	ncMeta metav1.ObjectMeta,
	ncSpec controlplanev1.NestedComponentSpec,
	ncKind controlplanev1.ComponentKind, controlPlaneName, clusterName string,
	log logr.Logger, ncSts *appsv1.StatefulSet) error {
	var templateURL string
	if ncSpec.Version == "" && ncSpec.Channel == "" {
		log.V(4).Info("The Version and Channel are not set, " +
			"will use the default template.")
		switch ncKind {
		case controlplanev1.APIServer:
			templateURL = templatePath + defaultKASStatefulSetURL
		case controlplanev1.Etcd:
			templateURL = templatePath + defaultEtcdStatefulSetURL
		case controlplanev1.ControllerManager:
			templateURL = templatePath + defaultKCMStatefulSetURL
		default:
			panic("Unreachable")
		}
	} else {
		panic("NOT IMPLEMENT YET")
	}
	stsTmpl, err := fetchTemplate(templateURL)
	if err != nil {
		return fmt.Errorf("fail to fetch the default template "+
			"for the %s StatefulSet: %v", ncKind, err)
	}
	templateCtx := getTemplateArgs(ncMeta, controlPlaneName, clusterName)
	stsStr, err := substituteTemplate(templateCtx, stsTmpl)
	if err != nil {
		return fmt.Errorf("fail to substitute the default template "+
			"for the %s StatefulSet: %v", ncKind, err)
	}
	if err := yamlToObject([]byte(stsStr), ncSts); err != nil {
		return fmt.Errorf("fail to convert yaml file to StatefulSet: %v", err)
	}
	log.V(5).Info("deserialize yaml to runtime object(StatefulSet)")
	for i := range ncSts.Spec.Template.Spec.Containers {
		ncSts.Spec.Template.Spec.Containers[i].Resources =
			ncSpec.Resources
	}
	if ncSpec.Replicas != 0 {
		ncSts.Spec.Replicas = &ncSpec.Replicas
	}
	log.V(5).Info("The NestedEtcd StatefulSet's Resources and "+
		"Replicas fields are set",
		"StatefulSet", ncSts.GetName())
	if ncKind == controlplanev1.Etcd {
		icaVal := genInitialClusterArgs(1, clusterName, clusterName, ncMeta.GetNamespace())
		stsArgs := append(ncSts.Spec.Template.Spec.Containers[0].Args,
			"--initial-cluster", icaVal)
		ncSts.Spec.Template.Spec.Containers[0].Args = stsArgs
		log.V(5).Info("The '--initial-cluster' command line option is set")
	}
	return nil
}
func getTemplateArgs(ncMeta metav1.ObjectMeta, controlPlaneName, clusterName string) map[string]string {
	return map[string]string{
		"componentName":      ncMeta.GetName(),
		"componentNamespace": ncMeta.GetNamespace(),
		"clusterName":        clusterName,
		"controlPlaneName":   controlPlaneName,
	}
}
func yamlToObject(yamlContent []byte, obj runtime.Object) error {
	decode := serializer.NewCodecFactory(scheme.Scheme).
		UniversalDeserializer().Decode
	_, _, err := decode(yamlContent, nil, obj)
	if err != nil {
		return err
	}
	return nil
}
func substituteTemplate(context interface{}, tmpl string) (string, error) {
	t, tmplPrsErr := template.New("test").
		Option("missingkey=zero").Parse(tmpl)
	if tmplPrsErr != nil {
		return "", tmplPrsErr
	}
	writer := bytes.NewBuffer([]byte{})
	if err := t.Execute(writer, context); nil != err {
		return "", err
	}
	return writer.String(), nil
}
func fetchTemplate(templateURL string) (string, error) {
	rep, err := openuri.Open(templateURL)
	if err != nil {
		return "", err
	}
	defer rep.Close()
	bodyBytes, err := ioutil.ReadAll(rep)
	if err != nil {
		return "", err
	}
	return string(bodyBytes), nil
}