fix: patching of kube-proxy and coredns advanced objects (#940)

* fix(coredns): using patch for deployment and service reconciliation

Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>

* feat(kubeproxy): using patch for daemonset reconciliation

Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>

---------

Signed-off-by: Dario Tranchitella <dario@tranchitella.eu>
This commit is contained in:
Dario Tranchitella
2025-09-04 16:56:09 +02:00
committed by GitHub
parent ef0e653729
commit b9fee273eb
2 changed files with 47 additions and 161 deletions

View File

@@ -292,87 +292,25 @@ func (c *CoreDNS) mutateClusterRoleBinding(ctx context.Context, tenantClient cli
}
func (c *CoreDNS) mutateDeployment(ctx context.Context, tenantClient client.Client) (controllerutil.OperationResult, error) {
d := &appsv1.Deployment{}
d.SetName(c.deployment.GetName())
d.SetNamespace(c.deployment.GetNamespace())
var deployment appsv1.Deployment
deployment.Name = c.deployment.Name
deployment.Namespace = c.deployment.Namespace
return utilities.CreateOrUpdateWithConflict(ctx, tenantClient, d, func() error {
d.SetLabels(utilities.MergeMaps(d.GetLabels(), c.deployment.GetLabels()))
d.SetAnnotations(utilities.MergeMaps(d.GetAnnotations(), c.deployment.GetAnnotations()))
d.Spec.Replicas = c.deployment.Spec.Replicas
d.Spec.Selector = c.deployment.Spec.Selector
d.Spec.Template.Labels = c.deployment.Spec.Selector.MatchLabels
if len(d.Spec.Template.Spec.Volumes) != 1 {
d.Spec.Template.Spec.Volumes = make([]corev1.Volume, 1)
if err := tenantClient.Get(ctx, client.ObjectKeyFromObject(&deployment), &deployment); err != nil {
if k8serrors.IsNotFound(err) {
return utilities.CreateOrUpdateWithConflict(ctx, tenantClient, &deployment, func() error {
return controllerutil.SetControllerReference(c.clusterRoleBinding, &deployment, tenantClient.Scheme())
})
}
d.Spec.Template.Spec.Volumes[0].Name = c.deployment.Spec.Template.Spec.Volumes[0].Name
if d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap == nil {
d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap = &corev1.ConfigMapVolumeSource{}
}
d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.LocalObjectReference.Name = c.deployment.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.LocalObjectReference.Name
if len(d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Items) == 0 {
d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Items = make([]corev1.KeyToPath, 1)
}
d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Key = c.deployment.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Key
d.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Path = c.deployment.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Path
if len(d.Spec.Template.Spec.Containers) == 0 {
d.Spec.Template.Spec.Containers = make([]corev1.Container, 1)
}
d.Spec.Template.Spec.Containers[0].Name = c.deployment.Spec.Template.Spec.Containers[0].Name
d.Spec.Template.Spec.Containers[0].Image = c.deployment.Spec.Template.Spec.Containers[0].Image
d.Spec.Template.Spec.Containers[0].Args = c.deployment.Spec.Template.Spec.Containers[0].Args
if len(d.Spec.Template.Spec.Containers[0].Ports) != 3 {
d.Spec.Template.Spec.Containers[0].Ports = make([]corev1.ContainerPort, 3)
}
d.Spec.Template.Spec.Containers[0].Ports[0].Name = c.deployment.Spec.Template.Spec.Containers[0].Ports[0].Name
d.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort = c.deployment.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort
d.Spec.Template.Spec.Containers[0].Ports[0].Protocol = c.deployment.Spec.Template.Spec.Containers[0].Ports[0].Protocol
d.Spec.Template.Spec.Containers[0].Ports[1].Name = c.deployment.Spec.Template.Spec.Containers[0].Ports[1].Name
d.Spec.Template.Spec.Containers[0].Ports[1].ContainerPort = c.deployment.Spec.Template.Spec.Containers[0].Ports[1].ContainerPort
d.Spec.Template.Spec.Containers[0].Ports[1].Protocol = c.deployment.Spec.Template.Spec.Containers[0].Ports[1].Protocol
d.Spec.Template.Spec.Containers[0].Ports[2].Name = c.deployment.Spec.Template.Spec.Containers[0].Ports[2].Name
d.Spec.Template.Spec.Containers[0].Ports[2].ContainerPort = c.deployment.Spec.Template.Spec.Containers[0].Ports[2].ContainerPort
d.Spec.Template.Spec.Containers[0].Ports[2].Protocol = c.deployment.Spec.Template.Spec.Containers[0].Ports[2].Protocol
d.Spec.Template.Spec.Containers[0].Resources = c.deployment.Spec.Template.Spec.Containers[0].Resources
if len(d.Spec.Template.Spec.Containers[0].VolumeMounts) == 0 {
d.Spec.Template.Spec.Containers[0].VolumeMounts = make([]corev1.VolumeMount, 1)
}
d.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name = c.deployment.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name
d.Spec.Template.Spec.Containers[0].VolumeMounts[0].ReadOnly = c.deployment.Spec.Template.Spec.Containers[0].VolumeMounts[0].ReadOnly
d.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath = c.deployment.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath
if d.Spec.Template.Spec.Containers[0].LivenessProbe == nil {
d.Spec.Template.Spec.Containers[0].LivenessProbe = &corev1.Probe{}
}
d.Spec.Template.Spec.Containers[0].LivenessProbe.HTTPGet = c.deployment.Spec.Template.Spec.Containers[0].LivenessProbe.HTTPGet
d.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds = c.deployment.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds
d.Spec.Template.Spec.Containers[0].LivenessProbe.TimeoutSeconds = c.deployment.Spec.Template.Spec.Containers[0].LivenessProbe.TimeoutSeconds
d.Spec.Template.Spec.Containers[0].LivenessProbe.SuccessThreshold = c.deployment.Spec.Template.Spec.Containers[0].LivenessProbe.SuccessThreshold
d.Spec.Template.Spec.Containers[0].LivenessProbe.FailureThreshold = c.deployment.Spec.Template.Spec.Containers[0].LivenessProbe.FailureThreshold
if d.Spec.Template.Spec.Containers[0].ReadinessProbe == nil {
d.Spec.Template.Spec.Containers[0].ReadinessProbe = &corev1.Probe{}
}
d.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet = c.deployment.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet
if d.Spec.Template.Spec.Containers[0].SecurityContext == nil {
d.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{}
}
d.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities = c.deployment.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities
d.Spec.Template.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem = c.deployment.Spec.Template.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem
d.Spec.Template.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = c.deployment.Spec.Template.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation
d.Spec.Template.Spec.DNSPolicy = c.deployment.Spec.Template.Spec.DNSPolicy
d.Spec.Template.Spec.NodeSelector = c.deployment.Spec.Template.Spec.NodeSelector
d.Spec.Template.Spec.ServiceAccountName = c.deployment.Spec.Template.Spec.ServiceAccountName
if d.Spec.Template.Spec.Affinity == nil {
d.Spec.Template.Spec.Affinity = &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{},
}
}
d.Spec.Template.Spec.Affinity.PodAffinity = c.deployment.Spec.Template.Spec.Affinity.PodAffinity
d.Spec.Template.Spec.Tolerations = c.deployment.Spec.Template.Spec.Tolerations
d.Spec.Template.Spec.PriorityClassName = c.deployment.Spec.Template.Spec.PriorityClassName
d.Spec.Strategy.Type = c.deployment.Spec.Strategy.Type
return controllerutil.SetControllerReference(c.clusterRoleBinding, d, tenantClient.Scheme())
})
return controllerutil.OperationResultNone, err
}
if err := controllerutil.SetControllerReference(c.clusterRoleBinding, c.deployment, tenantClient.Scheme()); err != nil {
return controllerutil.OperationResultNone, err
}
//nolint:staticcheck
return controllerutil.OperationResultNone, tenantClient.Patch(ctx, c.deployment, client.Apply, client.FieldOwner("kamaji"), client.ForceOwnership)
}
func (c *CoreDNS) mutateConfigMap(ctx context.Context, tenantClient client.Client) (controllerutil.OperationResult, error) {
@@ -390,20 +328,25 @@ func (c *CoreDNS) mutateConfigMap(ctx context.Context, tenantClient client.Clien
}
func (c *CoreDNS) mutateService(ctx context.Context, tenantClient client.Client) (controllerutil.OperationResult, error) {
svc := &corev1.Service{}
svc.SetName(c.service.GetName())
svc.SetNamespace(c.service.GetNamespace())
var svc corev1.Service
svc.Name = c.service.Name
svc.Namespace = c.service.Namespace
return utilities.CreateOrUpdateWithConflict(ctx, tenantClient, svc, func() error {
svc.SetLabels(utilities.MergeMaps(svc.GetLabels(), c.service.GetLabels()))
svc.SetAnnotations(utilities.MergeMaps(svc.GetAnnotations(), c.service.GetAnnotations()))
if err := tenantClient.Get(ctx, client.ObjectKeyFromObject(&svc), &svc); err != nil {
if k8serrors.IsNotFound(err) {
return utilities.CreateOrUpdateWithConflict(ctx, tenantClient, &svc, func() error {
return controllerutil.SetControllerReference(c.clusterRoleBinding, &svc, tenantClient.Scheme())
})
}
svc.Spec.Ports = c.service.Spec.Ports
svc.Spec.Selector = c.service.Spec.Selector
svc.Spec.ClusterIP = c.service.Spec.ClusterIP
return controllerutil.OperationResultNone, err
}
return controllerutil.SetControllerReference(c.clusterRoleBinding, svc, tenantClient.Scheme())
})
if err := controllerutil.SetControllerReference(c.clusterRoleBinding, c.service, tenantClient.Scheme()); err != nil {
return controllerutil.OperationResultNone, err
}
//nolint:staticcheck
return controllerutil.OperationResultNone, tenantClient.Patch(ctx, c.service, client.Apply, client.FieldOwner("kamaji"), client.ForceOwnership)
}
func (c *CoreDNS) mutateClusterRole(ctx context.Context, tenantClient client.Client) (controllerutil.OperationResult, error) {

View File

@@ -15,7 +15,6 @@ import (
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
pointer "k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -298,81 +297,25 @@ func (k *KubeProxy) mutateConfigMap(ctx context.Context, tenantClient client.Cli
}
func (k *KubeProxy) mutateDaemonSet(ctx context.Context, tenantClient client.Client) (controllerutil.OperationResult, error) {
ds := &appsv1.DaemonSet{}
ds.SetName(k.daemonSet.GetName())
ds.SetNamespace(k.daemonSet.GetNamespace())
var ds appsv1.DaemonSet
ds.Name = k.daemonSet.Name
ds.Namespace = k.daemonSet.Namespace
return utilities.CreateOrUpdateWithConflict(ctx, tenantClient, ds, func() error {
ds.SetLabels(utilities.MergeMaps(ds.GetLabels(), k.daemonSet.GetLabels()))
ds.SetAnnotations(utilities.MergeMaps(ds.GetAnnotations(), k.daemonSet.GetAnnotations()))
ds.Spec.Selector = k.daemonSet.Spec.Selector
if len(ds.Spec.Template.Spec.Volumes) != 3 {
ds.Spec.Template.Spec.Volumes = make([]corev1.Volume, 3)
}
ds.Spec.Template.ObjectMeta.SetLabels(k.daemonSet.Spec.Template.GetLabels())
ds.Spec.Template.Spec.Volumes[0].Name = k.daemonSet.Spec.Template.Spec.Volumes[0].Name
ds.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap = &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{Name: k.daemonSet.Spec.Template.Spec.Volumes[0].VolumeSource.ConfigMap.Name},
DefaultMode: pointer.To(int32(420)),
if err := tenantClient.Get(ctx, client.ObjectKeyFromObject(&ds), &ds); err != nil {
if k8serrors.IsNotFound(err) {
return utilities.CreateOrUpdateWithConflict(ctx, tenantClient, &ds, func() error {
return controllerutil.SetControllerReference(k.clusterRoleBinding, &ds, tenantClient.Scheme())
})
}
ds.Spec.Template.Spec.Volumes[1].Name = k.daemonSet.Spec.Template.Spec.Volumes[1].Name
ds.Spec.Template.Spec.Volumes[1].VolumeSource.HostPath = &corev1.HostPathVolumeSource{
Path: k.daemonSet.Spec.Template.Spec.Volumes[1].VolumeSource.HostPath.Path,
Type: func(v corev1.HostPathType) *corev1.HostPathType {
return &v
}(corev1.HostPathFileOrCreate),
}
return controllerutil.OperationResultNone, err
}
ds.Spec.Template.Spec.Volumes[2].Name = k.daemonSet.Spec.Template.Spec.Volumes[2].Name
ds.Spec.Template.Spec.Volumes[2].VolumeSource.HostPath = &corev1.HostPathVolumeSource{
Path: k.daemonSet.Spec.Template.Spec.Volumes[2].VolumeSource.HostPath.Path,
Type: func(v corev1.HostPathType) *corev1.HostPathType {
return &v
}(""),
}
if len(ds.Spec.Template.Spec.Containers) == 0 {
ds.Spec.Template.Spec.Containers = make([]corev1.Container, 1)
}
ds.Spec.Template.Spec.Containers[0].Name = k.daemonSet.Spec.Template.Spec.Containers[0].Name
ds.Spec.Template.Spec.Containers[0].Image = k.daemonSet.Spec.Template.Spec.Containers[0].Image
ds.Spec.Template.Spec.Containers[0].Command = k.daemonSet.Spec.Template.Spec.Containers[0].Command
if len(ds.Spec.Template.Spec.Containers[0].Env) == 0 {
ds.Spec.Template.Spec.Containers[0].Env = make([]corev1.EnvVar, 1)
}
ds.Spec.Template.Spec.Containers[0].Env[0].Name = k.daemonSet.Spec.Template.Spec.Containers[0].Env[0].Name
if ds.Spec.Template.Spec.Containers[0].Env[0].ValueFrom == nil {
ds.Spec.Template.Spec.Containers[0].Env[0].ValueFrom = &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{},
}
}
ds.Spec.Template.Spec.Containers[0].Env[0].ValueFrom.FieldRef.FieldPath = k.daemonSet.Spec.Template.Spec.Containers[0].Env[0].ValueFrom.FieldRef.FieldPath
if len(ds.Spec.Template.Spec.Containers[0].VolumeMounts) != 3 {
ds.Spec.Template.Spec.Containers[0].VolumeMounts = make([]corev1.VolumeMount, 3)
}
ds.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name
ds.Spec.Template.Spec.Containers[0].VolumeMounts[0].ReadOnly = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[0].ReadOnly
ds.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath
ds.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name
ds.Spec.Template.Spec.Containers[0].VolumeMounts[1].ReadOnly = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[1].ReadOnly
ds.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath
ds.Spec.Template.Spec.Containers[0].VolumeMounts[2].Name = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[2].Name
ds.Spec.Template.Spec.Containers[0].VolumeMounts[2].ReadOnly = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[2].ReadOnly
ds.Spec.Template.Spec.Containers[0].VolumeMounts[2].MountPath = k.daemonSet.Spec.Template.Spec.Containers[0].VolumeMounts[2].MountPath
if ds.Spec.Template.Spec.Containers[0].SecurityContext == nil {
ds.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{}
}
ds.Spec.Template.Spec.Containers[0].SecurityContext.Privileged = k.daemonSet.Spec.Template.Spec.Containers[0].SecurityContext.Privileged
ds.Spec.Template.Spec.NodeSelector = k.daemonSet.Spec.Template.Spec.NodeSelector
ds.Spec.Template.Spec.ServiceAccountName = k.daemonSet.Spec.Template.Spec.ServiceAccountName
ds.Spec.Template.Spec.HostNetwork = k.daemonSet.Spec.Template.Spec.HostNetwork
ds.Spec.Template.Spec.Tolerations = k.daemonSet.Spec.Template.Spec.Tolerations
ds.Spec.Template.Spec.PriorityClassName = k.daemonSet.Spec.Template.Spec.PriorityClassName
ds.Spec.UpdateStrategy.Type = k.daemonSet.Spec.UpdateStrategy.Type
return controllerutil.SetControllerReference(k.clusterRoleBinding, ds, tenantClient.Scheme())
})
if err := controllerutil.SetControllerReference(k.clusterRoleBinding, k.daemonSet, tenantClient.Scheme()); err != nil {
return controllerutil.OperationResultNone, err
}
//nolint:staticcheck
return controllerutil.OperationResultNone, tenantClient.Patch(ctx, k.daemonSet, client.Apply, client.FieldOwner("kamaji"), client.ForceOwnership)
}
func (k *KubeProxy) decodeManifests(ctx context.Context, tcp *kamajiv1alpha1.TenantControlPlane) error {