github.com/ironcore-dev/gardener-extension-provider-ironcore@v0.3.2-0.20240314231816-8336447fb9a0/pkg/webhook/controlplane/ensurer.go (about) 1 // SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and IronCore contributors 2 // SPDX-License-Identifier: Apache-2.0 3 4 package controlplane 5 6 import ( 7 "context" 8 9 "github.com/Masterminds/semver/v3" 10 "github.com/coreos/go-systemd/v22/unit" 11 extensionswebhook "github.com/gardener/gardener/extensions/pkg/webhook" 12 extensionscontextwebhook "github.com/gardener/gardener/extensions/pkg/webhook/context" 13 "github.com/gardener/gardener/extensions/pkg/webhook/controlplane/genericmutator" 14 extensionsv1alpha1 "github.com/gardener/gardener/pkg/apis/extensions/v1alpha1" 15 "github.com/gardener/gardener/pkg/component/machinecontrollermanager" 16 "github.com/go-logr/logr" 17 appsv1 "k8s.io/api/apps/v1" 18 corev1 "k8s.io/api/core/v1" 19 "k8s.io/apimachinery/pkg/api/resource" 20 vpaautoscalingv1 "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/apis/autoscaling.k8s.io/v1" 21 kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1" 22 23 "github.com/ironcore-dev/gardener-extension-provider-ironcore/imagevector" 24 "github.com/ironcore-dev/gardener-extension-provider-ironcore/pkg/ironcore" 25 ) 26 27 // NewEnsurer creates a new controlplane ensurer. 28 func NewEnsurer(logger logr.Logger, gardenletManagesMCM bool) genericmutator.Ensurer { 29 return &ensurer{ 30 logger: logger.WithName("ironcore-controlplane-ensurer"), 31 } 32 } 33 34 type ensurer struct { 35 genericmutator.NoopEnsurer 36 logger logr.Logger 37 } 38 39 // ImageVector is exposed for testing. 40 var ImageVector = imagevector.ImageVector() 41 42 // EnsureMachineControllerManagerDeployment ensures that the machine-controller-manager deployment conforms to the provider requirements. 43 func (e *ensurer) EnsureMachineControllerManagerDeployment(_ context.Context, _ extensionscontextwebhook.GardenContext, newObj, _ *appsv1.Deployment) error { 44 image, err := ImageVector.FindImage(ironcore.MachineControllerManagerProviderIroncoreImageName) 45 if err != nil { 46 return err 47 } 48 49 template := &newObj.Spec.Template 50 ps := &template.Spec 51 52 ps.Containers = extensionswebhook.EnsureContainerWithName( 53 newObj.Spec.Template.Spec.Containers, 54 machinecontrollermanager.ProviderSidecarContainer(newObj.Namespace, ironcore.ProviderName, image.String()), 55 ) 56 57 if c := extensionswebhook.ContainerWithName(ps.Containers, "machine-controller-manager-provider-ironcore"); c != nil { 58 ensureMCMCommandLineArgs(c) 59 c.VolumeMounts = extensionswebhook.EnsureVolumeMountWithName(c.VolumeMounts, corev1.VolumeMount{ 60 Name: "cloudprovider", 61 MountPath: "/etc/ironcore", 62 ReadOnly: true, 63 }) 64 } 65 66 ps.Volumes = extensionswebhook.EnsureVolumeWithName(ps.Volumes, corev1.Volume{ 67 Name: "cloudprovider", 68 VolumeSource: corev1.VolumeSource{ 69 Secret: &corev1.SecretVolumeSource{ 70 SecretName: "cloudprovider", 71 }, 72 }, 73 }) 74 75 return nil 76 } 77 78 // EnsureMachineControllerManagerVPA ensures that the machine-controller-manager VPA conforms to the provider requirements. 79 func (e *ensurer) EnsureMachineControllerManagerVPA(_ context.Context, _ extensionscontextwebhook.GardenContext, newObj, _ *vpaautoscalingv1.VerticalPodAutoscaler) error { 80 var ( 81 minAllowed = corev1.ResourceList{ 82 corev1.ResourceCPU: resource.MustParse("30m"), 83 corev1.ResourceMemory: resource.MustParse("64Mi"), 84 } 85 maxAllowed = corev1.ResourceList{ 86 corev1.ResourceCPU: resource.MustParse("2"), 87 corev1.ResourceMemory: resource.MustParse("5G"), 88 } 89 ) 90 91 if newObj.Spec.ResourcePolicy == nil { 92 newObj.Spec.ResourcePolicy = &vpaautoscalingv1.PodResourcePolicy{} 93 } 94 95 newObj.Spec.ResourcePolicy.ContainerPolicies = extensionswebhook.EnsureVPAContainerResourcePolicyWithName( 96 newObj.Spec.ResourcePolicy.ContainerPolicies, 97 machinecontrollermanager.ProviderSidecarVPAContainerPolicy(ironcore.ProviderName, minAllowed, maxAllowed), 98 ) 99 return nil 100 } 101 102 // EnsureKubeAPIServerDeployment ensures that the kube-apiserver deployment conforms to the provider requirements. 103 func (e *ensurer) EnsureKubeAPIServerDeployment(_ context.Context, _ extensionscontextwebhook.GardenContext, new, _ *appsv1.Deployment) error { 104 template := &new.Spec.Template 105 ps := &template.Spec 106 107 if c := extensionswebhook.ContainerWithName(ps.Containers, "kube-apiserver"); c != nil { 108 ensureKubeAPIServerCommandLineArgs(c) 109 } 110 111 return nil 112 } 113 114 // EnsureKubeControllerManagerDeployment ensures that the kube-controller-manager deployment conforms to the provider requirements. 115 func (e *ensurer) EnsureKubeControllerManagerDeployment(_ context.Context, _ extensionscontextwebhook.GardenContext, new, _ *appsv1.Deployment) error { 116 template := &new.Spec.Template 117 ps := &template.Spec 118 119 if c := extensionswebhook.ContainerWithName(ps.Containers, "kube-controller-manager"); c != nil { 120 ensureKubeControllerManagerCommandLineArgs(c) 121 } 122 123 return nil 124 } 125 126 // EnsureKubeSchedulerDeployment ensures that the kube-scheduler deployment conforms to the provider requirements. 127 func (e *ensurer) EnsureKubeSchedulerDeployment(_ context.Context, _ extensionscontextwebhook.GardenContext, _, _ *appsv1.Deployment) error { 128 return nil 129 } 130 131 // EnsureClusterAutoscalerDeployment ensures that the cluster-autoscaler deployment conforms to the provider requirements. 132 func (e *ensurer) EnsureClusterAutoscalerDeployment(_ context.Context, _ extensionscontextwebhook.GardenContext, _, _ *appsv1.Deployment) error { 133 return nil 134 } 135 136 func ensureMCMCommandLineArgs(c *corev1.Container) { 137 c.Command = extensionswebhook.EnsureStringWithPrefix(c.Command, "--ironcore-kubeconfig=", "/etc/ironcore/kubeconfig") 138 } 139 140 func ensureKubeAPIServerCommandLineArgs(c *corev1.Container) { 141 c.Command = extensionswebhook.EnsureNoStringWithPrefix(c.Command, "--cloud-provider=") 142 c.Command = extensionswebhook.EnsureNoStringWithPrefix(c.Command, "--cloud-config=") 143 } 144 145 func ensureKubeControllerManagerCommandLineArgs(c *corev1.Container) { 146 c.Command = extensionswebhook.EnsureStringWithPrefix(c.Command, "--cloud-provider=", "external") 147 c.Command = extensionswebhook.EnsureNoStringWithPrefix(c.Command, "--cloud-config=") 148 } 149 150 // EnsureKubeletServiceUnitOptions ensures that the kubelet.service unit options conform to the provider requirements. 151 func (e *ensurer) EnsureKubeletServiceUnitOptions(_ context.Context, _ extensionscontextwebhook.GardenContext, _ *semver.Version, new, _ []*unit.UnitOption) ([]*unit.UnitOption, error) { 152 if opt := extensionswebhook.UnitOptionWithSectionAndName(new, "Service", "ExecStart"); opt != nil { 153 command := extensionswebhook.DeserializeCommandLine(opt.Value) 154 command = ensureKubeletCommandLineArgs(command) 155 opt.Value = extensionswebhook.SerializeCommandLine(command, 1, " \\\n ") 156 } 157 158 new = extensionswebhook.EnsureUnitOption(new, &unit.UnitOption{ 159 Section: "Service", 160 Name: "ExecStartPre", 161 Value: `/bin/sh -c 'hostnamectl set-hostname $(hostname -f)'`, 162 }) 163 164 return new, nil 165 } 166 167 func ensureKubeletCommandLineArgs(command []string) []string { 168 command = extensionswebhook.EnsureStringWithPrefix(command, "--cloud-provider=", "external") 169 return command 170 } 171 172 // EnsureKubeletConfiguration ensures that the kubelet configuration conforms to the provider requirements. 173 func (e *ensurer) EnsureKubeletConfiguration(_ context.Context, _ extensionscontextwebhook.GardenContext, _ *semver.Version, _, _ *kubeletconfigv1beta1.KubeletConfiguration) error { 174 return nil 175 } 176 177 // EnsureKubernetesGeneralConfiguration ensures that the kubernetes general configuration conforms to the provider requirements. 178 func (e *ensurer) EnsureKubernetesGeneralConfiguration(_ context.Context, _ extensionscontextwebhook.GardenContext, _, _ *string) error { 179 return nil 180 } 181 182 // EnsureAdditionalUnits ensures that additional required system units are added. 183 func (e *ensurer) EnsureAdditionalUnits(_ context.Context, _ extensionscontextwebhook.GardenContext, _, _ *[]extensionsv1alpha1.Unit) error { 184 return nil 185 } 186 187 // EnsureAdditionalFiles ensures that additional required system files are added. 188 func (e *ensurer) EnsureAdditionalFiles(_ context.Context, _ extensionscontextwebhook.GardenContext, _, _ *[]extensionsv1alpha1.File) error { 189 return nil 190 }