karmada/operator/pkg/controlplane/apiserver/apiserver.go

149 lines
6.9 KiB
Go

package apiserver
import (
"fmt"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
kuberuntime "k8s.io/apimachinery/pkg/runtime"
clientset "k8s.io/client-go/kubernetes"
clientsetscheme "k8s.io/client-go/kubernetes/scheme"
operatorv1alpha1 "github.com/karmada-io/karmada/operator/pkg/apis/operator/v1alpha1"
"github.com/karmada-io/karmada/operator/pkg/constants"
"github.com/karmada-io/karmada/operator/pkg/util"
"github.com/karmada-io/karmada/operator/pkg/util/apiclient"
"github.com/karmada-io/karmada/operator/pkg/util/patcher"
)
// EnsureKarmadaAPIServer creates karmada apiserver deployment and service resource
func EnsureKarmadaAPIServer(client clientset.Interface, cfg *operatorv1alpha1.KarmadaComponents, name, namespace string, featureGates map[string]bool) error {
if err := installKarmadaAPIServer(client, cfg.KarmadaAPIServer, name, namespace, featureGates); err != nil {
return fmt.Errorf("failed to install karmada apiserver, err: %w", err)
}
return createKarmadaAPIServerService(client, cfg.KarmadaAPIServer, name, namespace)
}
// EnsureKarmadaAggregatedAPIServer creates karmada aggregated apiserver deployment and service resource
func EnsureKarmadaAggregatedAPIServer(client clientset.Interface, cfg *operatorv1alpha1.KarmadaComponents, name, namespace string, featureGates map[string]bool) error {
if err := installKarmadaAggregatedAPIServer(client, cfg.KarmadaAggregatedAPIServer, name, namespace, featureGates); err != nil {
return err
}
return createKarmadaAggregatedAPIServerService(client, name, namespace)
}
func installKarmadaAPIServer(client clientset.Interface, cfg *operatorv1alpha1.KarmadaAPIServer, name, namespace string, featureGates map[string]bool) error {
apiserverDeploymentBytes, err := util.ParseTemplate(KarmadaApiserverDeployment, struct {
DeploymentName, Namespace, Image, EtcdClientService string
ServiceSubnet, KarmadaCertsSecret, EtcdCertsSecret string
Replicas *int32
EtcdListenClientPort int32
}{
DeploymentName: util.KarmadaAPIServerName(name),
Namespace: namespace,
Image: cfg.Image.Name(),
EtcdClientService: util.KarmadaEtcdClientName(name),
ServiceSubnet: *cfg.ServiceSubnet,
KarmadaCertsSecret: util.KarmadaCertSecretName(name),
EtcdCertsSecret: util.EtcdCertSecretName(name),
Replicas: cfg.Replicas,
EtcdListenClientPort: constants.EtcdListenClientPort,
})
if err != nil {
return fmt.Errorf("error when parsing karmadaApiserver deployment template: %w", err)
}
apiserverDeployment := &appsv1.Deployment{}
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), apiserverDeploymentBytes, apiserverDeployment); err != nil {
return fmt.Errorf("error when decoding karmadaApiserver deployment: %w", err)
}
patcher.NewPatcher().WithAnnotations(cfg.Annotations).WithLabels(cfg.Labels).
WithExtraArgs(cfg.ExtraArgs).ForDeployment(apiserverDeployment)
if err := apiclient.CreateOrUpdateDeployment(client, apiserverDeployment); err != nil {
return fmt.Errorf("error when creating deployment for %s, err: %w", apiserverDeployment.Name, err)
}
return nil
}
func createKarmadaAPIServerService(client clientset.Interface, cfg *operatorv1alpha1.KarmadaAPIServer, name, namespace string) error {
karmadaApiserverServiceBytes, err := util.ParseTemplate(KarmadaApiserverService, struct {
ServiceName, Namespace, ServiceType string
}{
ServiceName: util.KarmadaAPIServerName(name),
Namespace: namespace,
ServiceType: string(cfg.ServiceType),
})
if err != nil {
return fmt.Errorf("error when parsing karmadaApiserver serive template: %w", err)
}
karmadaApiserverService := &corev1.Service{}
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), karmadaApiserverServiceBytes, karmadaApiserverService); err != nil {
return fmt.Errorf("error when decoding karmadaApiserver serive: %w", err)
}
if err := apiclient.CreateOrUpdateService(client, karmadaApiserverService); err != nil {
return fmt.Errorf("err when creating service for %s, err: %w", karmadaApiserverService.Name, err)
}
return nil
}
func installKarmadaAggregatedAPIServer(client clientset.Interface, cfg *operatorv1alpha1.KarmadaAggregatedAPIServer, name, namespace string, featureGates map[string]bool) error {
aggregatedAPIServerDeploymentBytes, err := util.ParseTemplate(KarmadaAggregatedAPIServerDeployment, struct {
DeploymentName, Namespace, Image, EtcdClientService string
KubeconfigSecret, KarmadaCertsSecret, EtcdCertsSecret string
Replicas *int32
EtcdListenClientPort int32
}{
DeploymentName: util.KarmadaAggregatedAPIServerName(name),
Namespace: namespace,
Image: cfg.Image.Name(),
EtcdClientService: util.KarmadaEtcdClientName(name),
KubeconfigSecret: util.AdminKubeconfigSercretName(name),
KarmadaCertsSecret: util.KarmadaCertSecretName(name),
EtcdCertsSecret: util.EtcdCertSecretName(name),
Replicas: cfg.Replicas,
EtcdListenClientPort: constants.EtcdListenClientPort,
})
if err != nil {
return fmt.Errorf("error when parsing karmadaAggregatedAPIServer deployment template: %w", err)
}
aggregatedAPIServerDeployment := &appsv1.Deployment{}
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), aggregatedAPIServerDeploymentBytes, aggregatedAPIServerDeployment); err != nil {
return fmt.Errorf("err when decoding karmadaApiserver deployment: %w", err)
}
patcher.NewPatcher().WithAnnotations(cfg.Annotations).WithLabels(cfg.Labels).
WithExtraArgs(cfg.ExtraArgs).WithFeatureGates(featureGates).ForDeployment(aggregatedAPIServerDeployment)
if err := apiclient.CreateOrUpdateDeployment(client, aggregatedAPIServerDeployment); err != nil {
return fmt.Errorf("error when creating deployment for %s, err: %w", aggregatedAPIServerDeployment.Name, err)
}
return nil
}
func createKarmadaAggregatedAPIServerService(client clientset.Interface, name, namespace string) error {
aggregatedAPIServerServiceBytes, err := util.ParseTemplate(KarmadaAggregatedAPIServerService, struct {
ServiceName, Namespace string
}{
ServiceName: util.KarmadaAggregatedAPIServerName(name),
Namespace: namespace,
})
if err != nil {
return fmt.Errorf("error when parsing karmadaAggregatedAPIServer serive template: %w", err)
}
aggregatedAPIServerService := &corev1.Service{}
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), aggregatedAPIServerServiceBytes, aggregatedAPIServerService); err != nil {
return fmt.Errorf("err when decoding karmadaAggregatedAPIServer serive: %w", err)
}
if err := apiclient.CreateOrUpdateService(client, aggregatedAPIServerService); err != nil {
return fmt.Errorf("err when creating service for %s, err: %w", aggregatedAPIServerService.Name, err)
}
return nil
}