diff --git a/controller/sync.go b/controller/sync.go index a738b9f02304b..03cfba904696e 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -212,6 +212,19 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha } trackingMethod := argo.GetTrackingMethod(m.settingsMgr) + namespaceMetadataModifier := func(un *unstructured.Unstructured) bool { + createNamespaceMetadata := app.Spec.SyncPolicy.CreateNamespaceMetadata + if un != nil && len(createNamespaceMetadata.Labels) > 0 { + un.SetLabels(createNamespaceMetadata.Labels) + return true + } + if un != nil && len(createNamespaceMetadata.Annotations) > 0 { + un.SetAnnotations(createNamespaceMetadata.Annotations) + return true + } + return false + } + syncCtx, cleanup, err := sync.NewSyncContext( compareResult.syncStatus.Revision, reconciliationResult, @@ -244,7 +257,10 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha kube.UnsetLabel(un, cdcommon.LabelKeyAppInstance) return true } - return false + return namespaceMetadataModifier(un) + }, func(un *unstructured.Unstructured) bool { + namespaceMetadataModifier(un) + return true }), sync.WithSyncWaveHook(delayBetweenSyncWaves), sync.WithPruneLast(syncOp.SyncOptions.HasOption(common.SyncOptionPruneLast)), diff --git a/go.mod b/go.mod index a1b94ac8ec10e..5cf9bbc4af064 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis v2.5.0+incompatible github.com/alicebob/miniredis/v2 v2.14.2 - github.com/argoproj/gitops-engine v0.7.1-0.20220804190909-2bc3fef13e07 + github.com/argoproj/gitops-engine v0.7.1-0.20220818164807-a56a8030319e github.com/argoproj/notifications-engine v0.3.1-0.20220812180936-4d8552b0775f github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 github.com/aws/aws-sdk-go v1.38.49 diff --git a/go.sum b/go.sum index 19f3b02f0acc3..ef8164c98e574 100644 --- a/go.sum +++ b/go.sum @@ -144,8 +144,8 @@ github.com/antonmedv/expr v1.8.9/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmH github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/appscode/go v0.0.0-20190808133642-1d4ef1f1c1e0/go.mod h1:iy07dV61Z7QQdCKJCIvUoDL21u6AIceRhZzyleh2ymc= -github.com/argoproj/gitops-engine v0.7.1-0.20220804190909-2bc3fef13e07 h1:d9zthkVnQATgEQz1wel4ge8JzcmYFPRtFuTEWzhniWA= -github.com/argoproj/gitops-engine v0.7.1-0.20220804190909-2bc3fef13e07/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc= +github.com/argoproj/gitops-engine v0.7.1-0.20220818164807-a56a8030319e h1:6LtEKwTexv7Fubf7g7c9xYwCk9ZIMIk2T92cFWXY5wg= +github.com/argoproj/gitops-engine v0.7.1-0.20220818164807-a56a8030319e/go.mod h1:WpA/B7tgwfz+sdNE3LqrTrb7ArEY1FOPI2pAGI0hfPc= github.com/argoproj/notifications-engine v0.3.1-0.20220812180936-4d8552b0775f h1:xTts6TJ/SBbY9zV8qpueokUd3+SlJN6Abt4W6lAjOKM= github.com/argoproj/notifications-engine v0.3.1-0.20220812180936-4d8552b0775f/go.mod h1:R3zlopt+/juYlebQc9Jarn9vBQ2xZruWOWjUNkfGY9M= github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc= diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 5543bc9d10705..6b00f87ed1d00 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -741,6 +741,17 @@ spec: (default: false)' type: boolean type: object + createNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object retry: description: Retry controls failed sync retry behavior properties: diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index 522aabc0d3345..daa171bfd2c30 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -740,6 +740,17 @@ spec: (default: false)' type: boolean type: object + createNamespaceMetadata: + properties: + labels: + additionalProperties: + type: string + type: object + annotations: + additionalProperties: + type: string + type: object + type: object retry: description: Retry controls failed sync retry behavior properties: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 84392fe8a6437..56ee9eab687dd 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -741,6 +741,17 @@ spec: (default: false)' type: boolean type: object + createNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object retry: description: Retry controls failed sync retry behavior properties: diff --git a/manifests/install.yaml b/manifests/install.yaml index 2ed7eee23e824..87b37e5f10ae0 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -741,6 +741,17 @@ spec: (default: false)' type: boolean type: object + createNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object retry: description: Retry controls failed sync retry behavior properties: diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index 28077aa59f926..66b97b7c66c73 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -11,7 +11,7 @@ import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". -option go_package = "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"; +option go_package = "v1alpha1"; // AWSAuthConfig is an AWS IAM authentication configuration message AWSAuthConfig { @@ -528,6 +528,12 @@ message ConnectionState { optional k8s.io.apimachinery.pkg.apis.meta.v1.Time attemptedAt = 3; } +message CreateNamespaceMetadata { + map labels = 1; + + map annotations = 2; +} + // EnvEntry represents an entry in the application's environment message EnvEntry { // Name is the name of the variable, usually expressed in uppercase @@ -1266,6 +1272,8 @@ message SyncPolicy { // Retry controls failed sync retry behavior optional RetryStrategy retry = 3; + + optional CreateNamespaceMetadata createNamespaceMetadata = 4; } // SyncPolicyAutomated controls the behavior of an automated sync diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 23b77d1134628..68d305a4008e9 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -698,6 +698,11 @@ func (o SyncOptions) HasOption(option string) bool { return false } +type CreateNamespaceMetadata struct { + Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,1,opt,name=labels"` + Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,2,opt,name=annotations"` +} + // SyncPolicy controls when a sync will be performed in response to updates in git type SyncPolicy struct { // Automated will keep an application synced to the target revision @@ -705,7 +710,8 @@ type SyncPolicy struct { // Options allow you to specify whole app sync-options SyncOptions SyncOptions `json:"syncOptions,omitempty" protobuf:"bytes,2,opt,name=syncOptions"` // Retry controls failed sync retry behavior - Retry *RetryStrategy `json:"retry,omitempty" protobuf:"bytes,3,opt,name=retry"` + Retry *RetryStrategy `json:"retry,omitempty" protobuf:"bytes,3,opt,name=retry"` + CreateNamespaceMetadata CreateNamespaceMetadata `json:"createNamespaceMetadata,omitempty" protobuf:"bytes,4,opt,name=createNamespaceMetadata"` } // IsZero returns true if the sync policy is empty diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 24d02c0caf087..52e8f7e3bf9d0 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -906,6 +906,36 @@ func (in *ConnectionState) DeepCopy() *ConnectionState { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CreateNamespaceMetadata) DeepCopyInto(out *CreateNamespaceMetadata) { + *out = *in + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CreateNamespaceMetadata. +func (in *CreateNamespaceMetadata) DeepCopy() *CreateNamespaceMetadata { + if in == nil { + return nil + } + out := new(CreateNamespaceMetadata) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in Env) DeepCopyInto(out *Env) { { @@ -2134,6 +2164,7 @@ func (in *SyncPolicy) DeepCopyInto(out *SyncPolicy) { *out = new(RetryStrategy) (*in).DeepCopyInto(*out) } + in.CreateNamespaceMetadata.DeepCopyInto(&out.CreateNamespaceMetadata) return }