Skip to content

Commit

Permalink
feat: Support additional metadata for controller
Browse files Browse the repository at this point in the history
Signed-off-by: Guillaume Doussin <[email protected]>
  • Loading branch information
OpenGuidou committed Apr 16, 2024
1 parent efd9a78 commit 4ff27a6
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 15 deletions.
11 changes: 11 additions & 0 deletions api/v1alpha1/argorollouts_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type RolloutManagerSpec struct {

// NamespaceScoped lets you specify if RolloutManager has to watch a namespace or the whole cluster
NamespaceScoped bool `json:"namespaceScoped,omitempty"`
// Metadata to apply to the controller resources
ControllerMetadata *ResourceMetadata `json:"controllerMetadata,omitempty"`
}

// ArgoRolloutsNodePlacementSpec is used to specify NodeSelector and Tolerations for Rollouts workloads
Expand Down Expand Up @@ -92,6 +94,15 @@ const (
RolloutManagerReasonInvalidScoped = "InvalidRolloutManagerScope"
)

type ResourceMetadata struct {
// Annotations to add to the resources during its creation.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// Labels to add to the resources during its creation.
// +optional
Labels map[string]string `json:"labels,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

Expand Down
34 changes: 34 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions config/crd/bases/argoproj.io_rolloutmanagers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ spec:
spec:
description: RolloutManagerSpec defines the desired state of Argo Rollouts
properties:
controllerMetadata:
description: Metadata to apply to the controller resources
properties:
annotations:
additionalProperties:
type: string
description: Annotations to add to the resources during its creation.
type: object
labels:
additionalProperties:
type: string
description: Labels to add to the resources during its creation.
type: object
type: object
env:
description: Env lets you specify environment for Rollouts pods
items:
Expand Down
28 changes: 21 additions & 7 deletions controllers/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,29 @@ func generateDesiredRolloutsDeployment(cr rolloutsmanagerv1alpha1.RolloutManager
Namespace: cr.Namespace,
},
}
setRolloutsLabelsAndAnnotationsToController(&desiredDeployment.ObjectMeta, &cr)

setRolloutsLabels(&desiredDeployment.ObjectMeta)
labels := map[string]string{
DefaultRolloutsSelectorKey: DefaultArgoRolloutsResourceName,
}
annotations := map[string]string{}
if cr.Spec.ControllerMetadata != nil {
for k, v := range cr.Spec.ControllerMetadata.Labels {
labels[k] = v
}
for k, v := range cr.Spec.ControllerMetadata.Annotations {
annotations[k] = v
}
}

desiredDeployment.Spec = appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
DefaultRolloutsSelectorKey: DefaultArgoRolloutsResourceName,
},
MatchLabels: labels,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
DefaultRolloutsSelectorKey: DefaultArgoRolloutsResourceName,
},
Labels: labels,
Annotations: annotations,
},
Spec: corev1.PodSpec{
NodeSelector: map[string]string{
Expand Down Expand Up @@ -123,6 +132,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsDeployment(ctx context.Conte
actualDeployment.Spec.Template.Spec.ServiceAccountName = desiredDeployment.Spec.Template.Spec.ServiceAccountName
actualDeployment.Labels = desiredDeployment.Labels
actualDeployment.Spec.Template.Labels = desiredDeployment.Spec.Template.Labels
actualDeployment.Spec.Template.Annotations = desiredDeployment.Spec.Template.Annotations
actualDeployment.Spec.Selector = desiredDeployment.Spec.Selector
actualDeployment.Spec.Template.Spec.NodeSelector = desiredDeployment.Spec.Template.Spec.NodeSelector
actualDeployment.Spec.Template.Spec.Tolerations = desiredDeployment.Spec.Template.Spec.Tolerations
Expand Down Expand Up @@ -155,6 +165,10 @@ func identifyDeploymentDifference(x appsv1.Deployment, y appsv1.Deployment) stri
return ".Spec.Template.Labels"
}

if !reflect.DeepEqual(x.Spec.Template.Annotations, y.Spec.Template.Annotations) {
return ".Spec.Template.Annotations"
}

if !reflect.DeepEqual(x.Spec.Selector, y.Spec.Selector) {
return ".Spec.Selector"
}
Expand Down
2 changes: 1 addition & 1 deletion controllers/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func deploymentCR(name string, namespace string, label string, volumeName string
Namespace: namespace,
},
}
setRolloutsLabels(&deploymentCR.ObjectMeta)
setRolloutsLabelsAndAnnotationsToController(&deploymentCR.ObjectMeta, rolloutManager)
deploymentCR.Spec = appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
Expand Down
12 changes: 6 additions & 6 deletions controllers/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsServiceAccount(ctx context.C
Namespace: cr.Namespace,
},
}
setRolloutsLabels(&sa.ObjectMeta)
setRolloutsLabelsAndAnnotations(&sa.ObjectMeta)

if err := fetchObject(ctx, r.Client, cr.Namespace, sa.Name, sa); err != nil {
if !apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -56,7 +56,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsRole(ctx context.Context, cr
Namespace: cr.Namespace,
},
}
setRolloutsLabels(&role.ObjectMeta)
setRolloutsLabelsAndAnnotations(&role.ObjectMeta)

if err := fetchObject(ctx, r.Client, cr.Namespace, role.Name, role); err != nil {
if !apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -92,7 +92,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsClusterRole(ctx context.Cont
Name: DefaultArgoRolloutsResourceName,
},
}
setRolloutsLabels(&clusterRole.ObjectMeta)
setRolloutsLabelsAndAnnotations(&clusterRole.ObjectMeta)

if err := fetchObject(ctx, r.Client, "", clusterRole.Name, clusterRole); err != nil {
if !apierrors.IsNotFound(err) {
Expand Down Expand Up @@ -131,7 +131,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsRoleBinding(ctx context.Cont
Namespace: cr.Namespace,
},
}
setRolloutsLabels(&expectedRoleBinding.ObjectMeta)
setRolloutsLabelsAndAnnotationsToController(&expectedRoleBinding.ObjectMeta, cr)

expectedRoleBinding.RoleRef = rbacv1.RoleRef{
APIGroup: rbacv1.GroupName,
Expand Down Expand Up @@ -191,7 +191,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsClusterRoleBinding(ctx conte
Name: DefaultArgoRolloutsResourceName,
},
}
setRolloutsLabels(&expectedClusterRoleBinding.ObjectMeta)
setRolloutsLabelsAndAnnotations(&expectedClusterRoleBinding.ObjectMeta)

expectedClusterRoleBinding.RoleRef = rbacv1.RoleRef{
APIGroup: rbacv1.GroupName,
Expand Down Expand Up @@ -345,7 +345,7 @@ func (r *RolloutManagerReconciler) reconcileRolloutsMetricsService(ctx context.C
Namespace: cr.Namespace,
},
}
setRolloutsLabels(&expectedSvc.ObjectMeta)
setRolloutsLabelsAndAnnotationsToController(&expectedSvc.ObjectMeta, cr)
// overwrite the annotations for Rollouts Metrics Service
expectedSvc.ObjectMeta.Labels["app.kubernetes.io/name"] = DefaultArgoRolloutsMetricsServiceName
expectedSvc.ObjectMeta.Labels["app.kubernetes.io/component"] = "server"
Expand Down
17 changes: 16 additions & 1 deletion controllers/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,23 @@ const (
UnsupportedRolloutManagerNamespaceScoped = "when Subscription has environment variable NAMESPACE_SCOPED_ARGO_ROLLOUTS set to False, there may not exist any namespace-scoped RolloutManagers: only a single cluster-scoped RolloutManager is supported"
)

func setRolloutsLabels(obj *metav1.ObjectMeta) {
func setRolloutsLabelsAndAnnotationsToController(obj *metav1.ObjectMeta, cr *rolloutsmanagerv1alpha1.RolloutManager) {

setRolloutsLabelsAndAnnotations(obj)

if cr.Spec.ControllerMetadata != nil {
for k, v := range cr.Spec.ControllerMetadata.Labels {
obj.Labels[k] = v
}
for k, v := range cr.Spec.ControllerMetadata.Annotations {
obj.Annotations[k] = v
}
}
}

func setRolloutsLabelsAndAnnotations(obj *metav1.ObjectMeta) {
obj.Labels = map[string]string{}
obj.Annotations = map[string]string{}
obj.Labels["app.kubernetes.io/name"] = DefaultArgoRolloutsResourceName
obj.Labels["app.kubernetes.io/part-of"] = DefaultArgoRolloutsResourceName
obj.Labels["app.kubernetes.io/component"] = DefaultArgoRolloutsResourceName
Expand Down
20 changes: 20 additions & 0 deletions docs/crd_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,23 @@ spec:
```


### RolloutManager example with metadata for the controller

You can provide labels and annotation for the Argo Rollouts controller.

``` yaml
``` yaml
apiVersion: argoproj.io/v1alpha1
kind: RolloutManager
metadata:
name: argo-rollout
labels:
example: nodeplacement-example
spec:
controllerMetadata:
labels:
mylabel: "true"
annotations:
myannotation: "myvalue"
```

15 changes: 15 additions & 0 deletions examples/custom_metadata_rolloutmanager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
apiVersion: argoproj.io/v1alpha1
kind: RolloutManager
metadata:
name: rollout-manager
labels:
example: withLabelsAndAnnotations
spec:
controllerMetadata:
labels:
exampleLabel: example-label
secondExampleLabel: second-example-label
annotations:
exampleAnnotation: example-annotation
secondExampleAnnotation: second-example-annotation
39 changes: 39 additions & 0 deletions tests/e2e/rollouts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,5 +239,44 @@ var _ = Describe("RolloutManager tests", func() {
}, "10s", "1s").Should(Equal(expectedVersion))
})
})

When("A RolloutManager specifies metadata", func() {

It("should create the controller with the correct labels and annotations", func() {

rolloutsManager := rolloutsmanagerv1alpha1.RolloutManager{
ObjectMeta: metav1.ObjectMeta{
Name: "basic-rollouts-manager-with-metadata",
Namespace: fixture.TestE2ENamespace,
},
Spec: rolloutsmanagerv1alpha1.RolloutManagerSpec{
ControllerMetadata: &rolloutsmanagerv1alpha1.ResourceMetadata{
Annotations: map[string]string{
"foo-annotation": "bar-annotation",
"foo-annotation2": "bar-annotation2",
},
Labels: map[string]string{
"foo-label": "bar-label",
"foo-label2": "bar-label2",
},
},
},
}

Expect(k8sClient.Create(ctx, &rolloutsManager)).To(Succeed())

Eventually(rolloutsManager, "60s", "1s").Should(rolloutManagerFixture.HavePhase(rolloutsmanagerv1alpha1.PhaseAvailable))

deployment := appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Name: controllers.DefaultArgoRolloutsResourceName, Namespace: fixture.TestE2ENamespace},
}
Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(&deployment), &deployment)).To(Succeed())

Expect(deployment.Spec.Template.ObjectMeta.Labels).To(HaveKeyWithValue("foo-label", "bar-label"))
Expect(deployment.Spec.Template.ObjectMeta.Labels).To(HaveKeyWithValue("foo-label2", "bar-label2"))
Expect(deployment.Spec.Template.ObjectMeta.Annotations).To(HaveKeyWithValue("foo-annotation", "bar-annotation"))
Expect(deployment.Spec.Template.ObjectMeta.Annotations).To(HaveKeyWithValue("foo-annotation2", "bar-annotation2"))
})
})
})
})

0 comments on commit 4ff27a6

Please sign in to comment.