From c449e49145e82878c97fed4c91b4a27e4eb261e5 Mon Sep 17 00:00:00 2001 From: Wahab Ali Date: Wed, 15 Jan 2025 21:56:53 +0500 Subject: [PATCH] Enable Sveltos Drift Detection --- api/v1alpha1/multiclusterservice_types.go | 8 ++ api/v1alpha1/zz_generated.deepcopy.go | 13 +++ config/dev/aws-clusterdeployment.yaml | 2 - .../clusterdeployment_controller.go | 3 + .../multiclusterservice_controller.go | 3 + internal/sveltos/profile.go | 16 +++ ...rdent.mirantis.com_clusterdeployments.yaml | 105 ++++++++++++++++++ ...ent.mirantis.com_multiclusterservices.yaml | 105 ++++++++++++++++++ 8 files changed, 253 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/multiclusterservice_types.go b/api/v1alpha1/multiclusterservice_types.go index a1d8c73fe..9ef8ab000 100644 --- a/api/v1alpha1/multiclusterservice_types.go +++ b/api/v1alpha1/multiclusterservice_types.go @@ -16,6 +16,7 @@ package v1alpha1 import ( sveltosv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1" + libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -92,6 +93,13 @@ type ServiceSpec struct { StopOnConflict bool `json:"stopOnConflict,omitempty"` // Reload instances via rolling upgrade when a ConfigMap/Secret mounted as volume is modified. Reload bool `json:"reload,omitempty"` + + // +kubebuilder:default:=Continuous + // +kubebuilder:validation:Enum:=OneTime;Continuous;ContinuousWithDriftDetection;DryRun + + SyncMode string `json:"syncMode,omitempty"` + IgnoreDrift []libsveltosv1beta1.PatchSelector `json:"ignoreDrift,omitempty"` + DriftExclusions []sveltosv1beta1.DriftExclusion `json:"driftExclusions,omitempty"` } // MultiClusterServiceSpec defines the desired state of MultiClusterService diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 3bd853ce1..5279740d4 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ import ( "github.com/fluxcd/helm-controller/api/v2" apiv1 "github.com/fluxcd/source-controller/api/v1" "github.com/projectsveltos/addon-controller/api/v1beta1" + apiv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1" velerov1 "github.com/zerospiel/velero/pkg/apis/velero/v1" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -1343,6 +1344,18 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { *out = make([]v1beta1.TemplateResourceRef, len(*in)) copy(*out, *in) } + if in.IgnoreDrift != nil { + in, out := &in.IgnoreDrift, &out.IgnoreDrift + *out = make([]apiv1beta1.PatchSelector, len(*in)) + copy(*out, *in) + } + if in.DriftExclusions != nil { + in, out := &in.DriftExclusions, &out.DriftExclusions + *out = make([]v1beta1.DriftExclusion, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpec. diff --git a/config/dev/aws-clusterdeployment.yaml b/config/dev/aws-clusterdeployment.yaml index 2991d51d0..d6b73387c 100644 --- a/config/dev/aws-clusterdeployment.yaml +++ b/config/dev/aws-clusterdeployment.yaml @@ -3,8 +3,6 @@ kind: ClusterDeployment metadata: name: aws-dev namespace: ${NAMESPACE} - labels: - k0rdent.mirantis.com/component: kcm spec: template: aws-standalone-cp-0-0-5 credential: aws-cluster-identity-cred diff --git a/internal/controller/clusterdeployment_controller.go b/internal/controller/clusterdeployment_controller.go index 790cc9ff2..8d7602b04 100644 --- a/internal/controller/clusterdeployment_controller.go +++ b/internal/controller/clusterdeployment_controller.go @@ -478,6 +478,9 @@ func (r *ClusterDeploymentReconciler) updateServices(ctx context.Context, mc *kc StopOnConflict: mc.Spec.ServiceSpec.StopOnConflict, Reload: mc.Spec.ServiceSpec.Reload, TemplateResourceRefs: mc.Spec.ServiceSpec.TemplateResourceRefs, + SyncMode: mc.Spec.ServiceSpec.SyncMode, + IgnoreDrift: mc.Spec.ServiceSpec.IgnoreDrift, + DriftExclusions: mc.Spec.ServiceSpec.DriftExclusions, }); err != nil { return ctrl.Result{}, fmt.Errorf("failed to reconcile Profile: %w", err) } diff --git a/internal/controller/multiclusterservice_controller.go b/internal/controller/multiclusterservice_controller.go index b17d53ed0..a5cc86953 100644 --- a/internal/controller/multiclusterservice_controller.go +++ b/internal/controller/multiclusterservice_controller.go @@ -142,6 +142,9 @@ func (r *MultiClusterServiceReconciler) reconcileUpdate(ctx context.Context, mcs StopOnConflict: mcs.Spec.ServiceSpec.StopOnConflict, Reload: mcs.Spec.ServiceSpec.Reload, TemplateResourceRefs: mcs.Spec.ServiceSpec.TemplateResourceRefs, + SyncMode: mcs.Spec.ServiceSpec.SyncMode, + IgnoreDrift: mcs.Spec.ServiceSpec.IgnoreDrift, + DriftExclusions: mcs.Spec.ServiceSpec.DriftExclusions, }); err != nil { return ctrl.Result{}, fmt.Errorf("failed to reconcile ClusterProfile: %w", err) } diff --git a/internal/sveltos/profile.go b/internal/sveltos/profile.go index 66c5058de..aa61ab4be 100644 --- a/internal/sveltos/profile.go +++ b/internal/sveltos/profile.go @@ -32,14 +32,21 @@ import ( "github.com/K0rdent/kcm/internal/utils" ) +const DrifIgnorePatch = `- op: add + path: /metadata/annotations/projectsveltos.io~1driftDetectionIgnore + value: ok` + type ReconcileProfileOpts struct { OwnerReference *metav1.OwnerReference LabelSelector metav1.LabelSelector HelmChartOpts []HelmChartOpts TemplateResourceRefs []sveltosv1beta1.TemplateResourceRef + IgnoreDrift []libsveltosv1beta1.PatchSelector + DriftExclusions []sveltosv1beta1.DriftExclusion Priority int32 StopOnConflict bool Reload bool + SyncMode string } type HelmChartOpts struct { @@ -238,7 +245,16 @@ func GetSpec(opts *ReconcileProfileOpts) (*sveltosv1beta1.Spec, error) { ContinueOnConflict: !opts.StopOnConflict, HelmCharts: make([]sveltosv1beta1.HelmChart, 0, len(opts.HelmChartOpts)), Reloader: opts.Reload, + SyncMode: sveltosv1beta1.SyncMode(opts.SyncMode), TemplateResourceRefs: opts.TemplateResourceRefs, + DriftExclusions: opts.DriftExclusions, + } + + for _, target := range opts.IgnoreDrift { + spec.Patches = append(spec.Patches, libsveltosv1beta1.Patch{ + Target: &target, + Patch: DrifIgnorePatch, + }) } for _, hc := range opts.HelmChartOpts { diff --git a/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_clusterdeployments.yaml b/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_clusterdeployments.yaml index aa35ec4eb..f6db61870 100644 --- a/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_clusterdeployments.yaml +++ b/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_clusterdeployments.yaml @@ -78,6 +78,103 @@ spec: serviceSpec: description: ServiceSpec is spec related to deployment of services. properties: + driftExclusions: + items: + properties: + paths: + description: Paths is a slice of JSON6902 paths to exclude + from configuration drift evaluation. + items: + type: string + type: array + target: + description: Target points to the resources that the paths + refers to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - paths + type: object + type: array + ignoreDrift: + items: + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + type: array priority: default: 100 description: |- @@ -172,6 +269,14 @@ spec: By default the remaining services will be deployed even if conflict is detected. If set to true, the deployment will stop after encountering the first conflict. type: boolean + syncMode: + default: Continuous + enum: + - OneTime + - Continuous + - ContinuousWithDriftDetection + - DryRun + type: string templateResourceRefs: description: |- TemplateResourceRefs is a list of resources to collect from the management cluster, diff --git a/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_multiclusterservices.yaml b/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_multiclusterservices.yaml index 894392566..68e79e63f 100644 --- a/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_multiclusterservices.yaml +++ b/templates/provider/kcm/templates/crds/k0rdent.mirantis.com_multiclusterservices.yaml @@ -90,6 +90,103 @@ spec: serviceSpec: description: ServiceSpec is spec related to deployment of services. properties: + driftExclusions: + items: + properties: + paths: + description: Paths is a slice of JSON6902 paths to exclude + from configuration drift evaluation. + items: + type: string + type: array + target: + description: Target points to the resources that the paths + refers to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - paths + type: object + type: array + ignoreDrift: + items: + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + type: array priority: default: 100 description: |- @@ -184,6 +281,14 @@ spec: By default the remaining services will be deployed even if conflict is detected. If set to true, the deployment will stop after encountering the first conflict. type: boolean + syncMode: + default: Continuous + enum: + - OneTime + - Continuous + - ContinuousWithDriftDetection + - DryRun + type: string templateResourceRefs: description: |- TemplateResourceRefs is a list of resources to collect from the management cluster,