From 1caabde5752157b6b22832e878e7c06ce42636d8 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 20 Jul 2023 08:25:18 -0400 Subject: [PATCH 01/94] fix: don't set phase to available during host reconciliation (#918) * upgrade golangci-lint Signed-off-by: Jaideep Rao * fix phase reconciliation during host reconciliation Signed-off-by: Jaideep Rao * address review comment Signed-off-by: Jaideep Rao * set phase to pending if ingress not found Signed-off-by: Jaideep Rao --------- Signed-off-by: Jaideep Rao --- controllers/argocd/status.go | 5 +---- controllers/argocd/status_test.go | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/controllers/argocd/status.go b/controllers/argocd/status.go index fb349dceb..da3e5f683 100644 --- a/controllers/argocd/status.go +++ b/controllers/argocd/status.go @@ -328,7 +328,6 @@ func (r *ReconcileArgoCD) reconcileStatusNotifications(cr *argoprojv1a1.ArgoCD) // reconcileStatusHost will ensure that the host status is updated for the given ArgoCD. func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoprojv1a1.ArgoCD) error { cr.Status.Host = "" - cr.Status.Phase = "Available" if (cr.Spec.Server.Route.Enabled || cr.Spec.Server.Ingress.Enabled) && IsRouteAPIAvailable() { route := newRouteWithSuffix("server", cr) @@ -365,7 +364,6 @@ func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoprojv1a1.ArgoCD) error { if len(route.Status.Ingress[0].Conditions) > 0 && route.Status.Ingress[0].Conditions[0].Type == routev1.RouteAdmitted { if route.Status.Ingress[0].Conditions[0].Status == corev1.ConditionTrue { cr.Status.Host = route.Status.Ingress[0].Host - cr.Status.Phase = "Available" } else { cr.Status.Host = "" cr.Status.Phase = "Pending" @@ -374,7 +372,6 @@ func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoprojv1a1.ArgoCD) error { // no conditions are available if route.Status.Ingress[0].Host != "" { cr.Status.Host = route.Status.Ingress[0].Host - cr.Status.Phase = "Available" } else { cr.Status.Host = "Unavailable" cr.Status.Phase = "Pending" @@ -386,6 +383,7 @@ func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoprojv1a1.ArgoCD) error { ingress := newIngressWithSuffix("server", cr) if !argoutil.IsObjectFound(r.Client, cr.Namespace, ingress.Name, ingress) { log.Info("argocd-server ingress requested but not found on cluster") + cr.Status.Phase = "Pending" return nil } else { if !reflect.DeepEqual(ingress.Status.LoadBalancer, corev1.LoadBalancerStatus{}) && len(ingress.Status.LoadBalancer.Ingress) > 0 { @@ -402,7 +400,6 @@ func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoprojv1a1.ArgoCD) error { } hosts = strings.Join(s, ", ") cr.Status.Host = hosts - cr.Status.Phase = "Available" } } } diff --git a/controllers/argocd/status_test.go b/controllers/argocd/status_test.go index 0686cd3d7..5c736038d 100644 --- a/controllers/argocd/status_test.go +++ b/controllers/argocd/status_test.go @@ -152,7 +152,6 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { expectedNil bool expectedHost bool host string - phase string }{ { name: "", @@ -161,7 +160,6 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { ingressEnabled: false, expectedNil: false, host: "argocd", - phase: "Available", }, { name: "", @@ -170,7 +168,6 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { ingressEnabled: true, expectedNil: false, host: "argocd, 12.0.0.5", - phase: "Available", }, } for _, test := range tests { @@ -250,7 +247,6 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { assert.NoError(t, err) assert.Equal(t, test.host, a.Status.Host) - assert.Equal(t, test.phase, a.Status.Phase) }) } } From 4d09acaf2d892ef80fb21cac07b0f516d8047677 Mon Sep 17 00:00:00 2001 From: Regina Scott <50851526+reginapizza@users.noreply.github.com> Date: Wed, 26 Jul 2023 07:19:49 +0100 Subject: [PATCH 02/94] update owners file (#953) --- OWNERS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OWNERS b/OWNERS index c205cd160..32f10999c 100644 --- a/OWNERS +++ b/OWNERS @@ -14,3 +14,7 @@ reviewers: - jopit - jaideepr97 - ishitasequeira +- reginapizza +- ciiay +- svghadi + From 45f3597f28e40c4aa3ce3a899b9228e953d8188a Mon Sep 17 00:00:00 2001 From: Salem Elrahal Date: Wed, 26 Jul 2023 15:51:03 +0100 Subject: [PATCH 03/94] Move to only adding two roles for managed namespaces (#954) * Move to only adding two roles for managed namespaces --------- Signed-off-by: Salem Elrahal Co-authored-by: Salem Elrahal --- controllers/argocd/role.go | 4 ++-- controllers/argocd/role_test.go | 18 ++++++++++++++++-- controllers/argocd/rolebinding.go | 4 ++-- controllers/argocd/rolebinding_test.go | 14 +++++++++++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/controllers/argocd/role.go b/controllers/argocd/role.go index 3eec12ff3..d21ffcbce 100644 --- a/controllers/argocd/role.go +++ b/controllers/argocd/role.go @@ -121,8 +121,8 @@ func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule } // only skip creation of dex and redisHa roles for namespaces that no argocd instance is deployed in if len(list.Items) < 1 { - // only create dexServer and redisHa roles for the namespace where the argocd instance is deployed - if cr.ObjectMeta.Namespace != namespace.Name && (name == common.ArgoCDDexServerComponent || name == common.ArgoCDRedisHAComponent) { + // namespace doesn't contain argocd instance, so skipe all the ArgoCD internal roles + if cr.ObjectMeta.Namespace != namespace.Name && (name != common.ArgoCDApplicationControllerComponent && name != common.ArgoCDServerComponent) { continue } } diff --git a/controllers/argocd/role_test.go b/controllers/argocd/role_test.go index eb84550ec..cf68dbe68 100644 --- a/controllers/argocd/role_test.go +++ b/controllers/argocd/role_test.go @@ -25,7 +25,7 @@ func TestReconcileArgoCD_reconcileRole(t *testing.T) { assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "newNamespaceTest", a.Namespace)) - workloadIdentifier := "x" + workloadIdentifier := common.ArgoCDApplicationControllerComponent expectedRules := policyRuleForApplicationController() _, err := r.reconcileRole(workloadIdentifier, expectedRules, a) assert.NoError(t, err) @@ -74,6 +74,20 @@ func TestReconcileArgoCD_reconcileRole_for_new_namespace(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expectedNumberOfRoles, len(redisHaRoles)) assert.Equal(t, expectedRoleNamespace, redisHaRoles[0].ObjectMeta.Namespace) + // check no redis role is created for the new namespace with managed-by label + workloadIdentifier = common.ArgoCDRedisComponent + expectedRedisRules := policyRuleForRedis(r.Client) + redisRoles, err := r.reconcileRole(workloadIdentifier, expectedRedisRules, a) + assert.NoError(t, err) + assert.Equal(t, expectedNumberOfRoles, len(redisRoles)) + assert.Equal(t, expectedRoleNamespace, redisRoles[0].ObjectMeta.Namespace) + // check no grafana role is created for the new namespace with managed-by label + workloadIdentifier = common.ArgoCDOperatorGrafanaComponent + expectedGrafanaRules := policyRuleForGrafana(r.Client) + grafanaRoles, err := r.reconcileRole(workloadIdentifier, expectedGrafanaRules, a) + assert.NoError(t, err) + assert.Equal(t, expectedNumberOfRoles, len(grafanaRoles)) + assert.Equal(t, expectedRoleNamespace, grafanaRoles[0].ObjectMeta.Namespace) } func TestReconcileArgoCD_reconcileClusterRole(t *testing.T) { @@ -217,7 +231,7 @@ func TestReconcileRoles_ManagedTerminatingNamespace(t *testing.T) { // Create a managed namespace assert.NoError(t, createNamespace(r, "managedNS", a.Namespace)) - workloadIdentifier := "x" + workloadIdentifier := common.ArgoCDApplicationControllerComponent expectedRules := policyRuleForApplicationController() _, err := r.reconcileRole(workloadIdentifier, expectedRules, a) assert.NoError(t, err) diff --git a/controllers/argocd/rolebinding.go b/controllers/argocd/rolebinding.go index 2547b5bfb..3f614be64 100644 --- a/controllers/argocd/rolebinding.go +++ b/controllers/argocd/rolebinding.go @@ -128,8 +128,8 @@ func (r *ReconcileArgoCD) reconcileRoleBinding(name string, rules []v1.PolicyRul } // only skip creation of dex and redisHa rolebindings for namespaces that no argocd instance is deployed in if len(list.Items) < 1 { - // only create dexServer and redisHa rolebindings for the namespace where the argocd instance is deployed - if cr.ObjectMeta.Namespace != namespace.Name && (name == common.ArgoCDDexServerComponent || name == common.ArgoCDRedisHAComponent) { + // namespace doesn't contain argocd instance, so skipe all the ArgoCD internal roles + if cr.ObjectMeta.Namespace != namespace.Name && (name != common.ArgoCDApplicationControllerComponent && name != common.ArgoCDServerComponent) { continue } } diff --git a/controllers/argocd/rolebinding_test.go b/controllers/argocd/rolebinding_test.go index 89a5d3767..e922d21b8 100644 --- a/controllers/argocd/rolebinding_test.go +++ b/controllers/argocd/rolebinding_test.go @@ -25,7 +25,7 @@ func TestReconcileArgoCD_reconcileRoleBinding(t *testing.T) { assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "newTestNamespace", a.Namespace)) - workloadIdentifier := "xrb" + workloadIdentifier := common.ArgoCDApplicationControllerComponent assert.NoError(t, r.reconcileRoleBinding(workloadIdentifier, p, a)) @@ -67,6 +67,18 @@ func TestReconcileArgoCD_reconcileRoleBinding_for_new_namespace(t *testing.T) { expectedRedisHaRules := policyRuleForRedisHa(r.Client) assert.NoError(t, r.reconcileRoleBinding(workloadIdentifier, expectedRedisHaRules, a)) assert.Error(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: expectedName, Namespace: "newTestNamespace"}, roleBinding)) + + // check no redis rolebinding is created for the new namespace with managed-by label + workloadIdentifier = common.ArgoCDRedisComponent + expectedRedisRules := policyRuleForRedis(r.Client) + assert.NoError(t, r.reconcileRoleBinding(workloadIdentifier, expectedRedisRules, a)) + assert.Error(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: expectedName, Namespace: "newTestNamespace"}, roleBinding)) + + // check no grafana rolebinding is created for the new namespace with managed-by label + workloadIdentifier = common.ArgoCDOperatorGrafanaComponent + expectedGrafanaRules := policyRuleForGrafana(r.Client) + assert.NoError(t, r.reconcileRoleBinding(workloadIdentifier, expectedGrafanaRules, a)) + assert.Error(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: expectedName, Namespace: "newTestNamespace"}, roleBinding)) } // This test validates the behavior of the operator reconciliation when a managed namespace is not properly terminated From c7cfa8c8cdba5b1ea0ed94ef2e9b566a43dd803c Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Tue, 1 Aug 2023 17:53:28 -0400 Subject: [PATCH 04/94] feat: expose operator metrics (#928) Track and expose custom operator performance metrics --------- Signed-off-by: Jaideep Rao --- ...er-manager-metrics-service_v1_service.yaml | 2 +- ...argocd-operator.clusterserviceversion.yaml | 13 ----- common/defaults.go | 2 + config/default/kustomization.yaml | 4 +- config/rbac/auth_proxy_service.yaml | 2 +- controllers/argocd/argocd_controller.go | 47 +++++++++++++++++++ controllers/argocd/metrics.go | 43 +++++++++++++++++ ...er-manager-metrics-service_v1_service.yaml | 2 +- ...operator.v0.7.0.clusterserviceversion.yaml | 13 ----- docs/usage/metrics.md | 9 ++++ go.mod | 2 +- main.go | 2 +- 12 files changed, 108 insertions(+), 33 deletions(-) create mode 100644 controllers/argocd/metrics.go create mode 100644 docs/usage/metrics.md diff --git a/bundle/manifests/argocd-operator-controller-manager-metrics-service_v1_service.yaml b/bundle/manifests/argocd-operator-controller-manager-metrics-service_v1_service.yaml index e7da1c70d..8d1547d9a 100644 --- a/bundle/manifests/argocd-operator-controller-manager-metrics-service_v1_service.yaml +++ b/bundle/manifests/argocd-operator-controller-manager-metrics-service_v1_service.yaml @@ -9,7 +9,7 @@ spec: ports: - name: https port: 8443 - targetPort: https + targetPort: 8080 selector: control-plane: argocd-operator status: diff --git a/bundle/manifests/argocd-operator.clusterserviceversion.yaml b/bundle/manifests/argocd-operator.clusterserviceversion.yaml index 73f8f8544..8b0f9b67f 100644 --- a/bundle/manifests/argocd-operator.clusterserviceversion.yaml +++ b/bundle/manifests/argocd-operator.clusterserviceversion.yaml @@ -1042,19 +1042,6 @@ spec: spec: containers: - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=10 - image: gcr.io/kubebuilder/kube-rbac-proxy@sha256:db06cc4c084dd0253134f156dddaaf53ef1c3fb3cc809e5d81711baa4029ea4c - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - resources: {} - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - --leader-elect command: - /manager diff --git a/common/defaults.go b/common/defaults.go index 05402b143..1a538bc39 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -304,6 +304,8 @@ gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgM ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H ` + // OperatorMetricsPort is the port that is used to expose default controller-runtime metrics for the operator pod. + OperatorMetricsPort = 8080 ) // DefaultLabels returns the default set of labels for controllers. diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 4a75d8d40..05ab0e7e5 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -22,13 +22,13 @@ bases: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. #- ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus +# - ../prometheus patchesStrategicMerge: # Protect the /metrics endpoint by putting it behind auth. # If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line. -- manager_auth_proxy_patch.yaml +# - manager_auth_proxy_patch.yaml # Mount the controller config file for loading manager configurations # through a ComponentConfig type diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml index 7e3675472..0c214c55a 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/rbac/auth_proxy_service.yaml @@ -9,6 +9,6 @@ spec: ports: - name: https port: 8443 - targetPort: https + targetPort: 8080 selector: control-plane: argocd-operator diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index e2e7abb00..e03fd76f8 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -19,8 +19,10 @@ package argocd import ( "context" "fmt" + "time" argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + "github.com/prometheus/client_golang/prometheus" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -47,6 +49,12 @@ type ReconcileArgoCD struct { var log = logr.Log.WithName("controller_argocd") +// Map to keep track of running Argo CD instances using their namespaces as key and phase as value +// This map will be used for the performance metrics purposes +// Important note: This assumes that each instance only contains one Argo CD instance +// as, having multiple Argo CD instances in the same namespace is considered an anti-pattern +var ActiveInstanceMap = make(map[string]string) + //+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings,verbs=* //+kubebuilder:rbac:groups="",resources=configmaps;endpoints;events;persistentvolumeclaims;pods;namespaces;secrets;serviceaccounts;services;services/finalizers,verbs=* //+kubebuilder:rbac:groups=apps.openshift.io,resources=deploymentconfigs,verbs=* @@ -74,6 +82,12 @@ var log = logr.Log.WithName("controller_argocd") // For more details, check Reconcile and its Result here: // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.9.2/pkg/reconcile func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { + + reconcileStartTS := time.Now() + defer func() { + ReconcileTime.WithLabelValues(request.Namespace).Observe(time.Since(reconcileStartTS).Seconds()) + }() + reqLogger := logr.FromContext(ctx, "namespace", request.Namespace, "name", request.Name) reqLogger.Info("Reconciling ArgoCD") @@ -90,7 +104,40 @@ func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) ( return reconcile.Result{}, err } + newPhase := argocd.Status.Phase + // If we discover a new Argo CD instance in a previously un-seen namespace + // we add it to the map and increment active instance count by phase + // as well as total active instance count + if _, ok := ActiveInstanceMap[request.Namespace]; !ok { + if newPhase != "" { + ActiveInstanceMap[request.Namespace] = newPhase + ActiveInstancesByPhase.WithLabelValues(newPhase).Inc() + ActiveInstancesTotal.Inc() + } + } else { + // If we discover an existing instance's phase has changed since we last saw it + // increment instance count with new phase and decrement instance count with old phase + // update the phase in corresponding map entry + // total instance count remains the same + if oldPhase := ActiveInstanceMap[argocd.Namespace]; oldPhase != newPhase { + ActiveInstanceMap[argocd.Namespace] = newPhase + ActiveInstancesByPhase.WithLabelValues(newPhase).Inc() + ActiveInstancesByPhase.WithLabelValues(oldPhase).Dec() + } + } + + ActiveInstanceReconciliationCount.WithLabelValues(argocd.Namespace).Inc() + if argocd.GetDeletionTimestamp() != nil { + + // Argo CD instance marked for deletion; remove entry from activeInstances map and decrement active instance count + // by phase as well as total + delete(ActiveInstanceMap, argocd.Namespace) + ActiveInstancesByPhase.WithLabelValues(newPhase).Dec() + ActiveInstancesTotal.Dec() + ActiveInstanceReconciliationCount.DeleteLabelValues(argocd.Namespace) + ReconcileTime.DeletePartialMatch(prometheus.Labels{"namespace": argocd.Namespace}) + if argocd.IsDeletionFinalizerPresent() { if err := r.deleteClusterResources(argocd); err != nil { return reconcile.Result{}, fmt.Errorf("failed to delete ClusterResources: %w", err) diff --git a/controllers/argocd/metrics.go b/controllers/argocd/metrics.go new file mode 100644 index 000000000..4a19c1d28 --- /dev/null +++ b/controllers/argocd/metrics.go @@ -0,0 +1,43 @@ +package argocd + +import ( + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + ActiveInstancesByPhase = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "active_argocd_instances_by_phase", + Help: "Number of active argocd instances by phase", + }, + []string{"phase"}, + ) + + ActiveInstancesTotal = prometheus.NewGauge( + prometheus.GaugeOpts{ + Name: "active_argocd_instances_total", + Help: "Total number of active argocd instances", + }, + ) + + ActiveInstanceReconciliationCount = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "active_argocd_instance_reconciliation_count", + Help: "Number of reconciliations performed for a given instance", + }, + []string{"namespace"}, + ) + + // ReconcileTime is a prometheus metric which keeps track of the duration + // of reconciliations for a given instance + ReconcileTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "controller_runtime_reconcile_time_seconds_per_instance", + Help: "Length of time per reconciliation per instance", + Buckets: []float64{0.05, 0.075, 0.1, 0.15, 0.2, 0.22, 0.24, 0.26, 0.28, 0.3, 0.32, 0.34, 0.37, 0.4, 0.42, 0.44, 0.48, 0.5, 0.55, 0.6, 0.75, 0.9, 1.00}, + }, []string{"namespace"}) +) + +func init() { + metrics.Registry.MustRegister(ActiveInstancesTotal, ActiveInstancesByPhase, ActiveInstanceReconciliationCount, ReconcileTime) +} diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml index e7da1c70d..8d1547d9a 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml @@ -9,7 +9,7 @@ spec: ports: - name: https port: 8443 - targetPort: https + targetPort: 8080 selector: control-plane: argocd-operator status: diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml index 73f8f8544..8b0f9b67f 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml @@ -1042,19 +1042,6 @@ spec: spec: containers: - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=10 - image: gcr.io/kubebuilder/kube-rbac-proxy@sha256:db06cc4c084dd0253134f156dddaaf53ef1c3fb3cc809e5d81711baa4029ea4c - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - resources: {} - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - --leader-elect command: - /manager diff --git a/docs/usage/metrics.md b/docs/usage/metrics.md new file mode 100644 index 000000000..68c1ccf55 --- /dev/null +++ b/docs/usage/metrics.md @@ -0,0 +1,9 @@ +# Metrics + +The Argo CD Operator exposes a set of performance metrics at port `8080`. It also creates a metrics-service called `argocd-operator-controller-manager-metrics-service`, present in the `argocd-operator-system` namespace, which makes the metrics available on port `8443` + +The metrics exposed by the operator currently are: +- `active_argocd_instances_total` [Guage] - This metric produces the graph that tracks the total number of active argo-cd instances being managed by the operator at a given time +- `active_argocd_instances_by_phase{phase=\"\"}` [Guage] - This metric produces the graph that tracks the count of active Argo CD instances by their phase [Available/Pending/Failed/unknown] +- `active_argocd_instance_reconciliation_count{namespace=\"\"}` [Counter] - This metric produces the graph that tracks total number of reconciliations that have occurred for the instance in the given namespace at any given point in time +- `controller_runtime_reconcile_time_seconds_per_instance_bucket{namespace=\"\",le=\"0.5\"}` [Histogram]- This metric tracks the number of reconciliations that took under 0.5s to complete for a given instance. The operator has a set of pre-configured buckets. \ No newline at end of file diff --git a/go.mod b/go.mod index 29f03b302..6c65e1aa8 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/openshift/client-go v0.0.0-20200325131901-f7baeb993edb github.com/operator-framework/operator-sdk v0.18.2 github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.15.1 github.com/sethvargo/go-password v0.2.0 github.com/stretchr/testify v1.8.2 golang.org/x/mod v0.10.0 @@ -59,7 +60,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.15.1 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.43.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect diff --git a/main.go b/main.go index e35557025..828e5b0f6 100644 --- a/main.go +++ b/main.go @@ -77,7 +77,7 @@ func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string - flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") + flag.StringVar(&metricsAddr, "metrics-bind-address", fmt.Sprintf(":%d", common.OperatorMetricsPort), "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ From 89825dbd902f6f5955ed908d79073a4e111a9104 Mon Sep 17 00:00:00 2001 From: Regina Scott <50851526+reginapizza@users.noreply.github.com> Date: Thu, 17 Aug 2023 15:18:44 +0100 Subject: [PATCH 05/94] add build.os config for readthedocs (#967) --- .readthedocs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index b6e297a8d..9c3cb3e22 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -8,3 +8,7 @@ mkdocs: python: install: - requirements: docs/requirements.txt +build: + os: "ubuntu-22.04" + tools: + python: "3.7" From 11299b7d576b5b85aa65d9569e8ae9176071d348 Mon Sep 17 00:00:00 2001 From: Regina Scott <50851526+reginapizza@users.noreply.github.com> Date: Mon, 21 Aug 2023 01:52:37 -0400 Subject: [PATCH 06/94] setup 0.8.0 (#966) --- Makefile | 2 +- ...argocd-operator.clusterserviceversion.yaml | 8 +- config/manager/kustomization.yaml | 2 +- ...argocd-operator.clusterserviceversion.yaml | 4 +- ...er-manager-metrics-service_v1_service.yaml | 9 +- ...-operator-manager-config_v1_configmap.yaml | 2 +- ...c.authorization.k8s.io_v1_clusterrole.yaml | 2 +- ...operator.v0.7.0.clusterserviceversion.yaml | 80 +- .../0.7.0/argoproj.io_applications.yaml | 19 +- .../0.7.0/argoproj.io_applicationsets.yaml | 2 +- .../0.7.0/argoproj.io_appprojects.yaml | 2 +- .../0.7.0/argoproj.io_argocdexports.yaml | 2 +- .../0.7.0/argoproj.io_argocds.yaml | 133 +- ...er-manager-metrics-service_v1_service.yaml | 16 + ...-operator-manager-config_v1_configmap.yaml | 17 + ...c.authorization.k8s.io_v1_clusterrole.yaml | 10 + ...operator.v0.8.0.clusterserviceversion.yaml | 1140 ++ .../0.8.0/argoproj.io_applications.yaml | 4365 ++++++ .../0.8.0/argoproj.io_applicationsets.yaml | 11584 ++++++++++++++++ .../0.8.0/argoproj.io_appprojects.yaml | 329 + .../0.8.0/argoproj.io_argocdexports.yaml | 258 + .../0.8.0/argoproj.io_argocds.yaml | 6373 +++++++++ .../argocd-operator.package.yaml | 2 +- 23 files changed, 24282 insertions(+), 79 deletions(-) create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-manager-config_v1_configmap.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_appprojects.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml diff --git a/Makefile b/Makefile index 226f1ae93..5c628bc84 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.7.0 +VERSION ?= 0.8.0 # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") diff --git a/bundle/manifests/argocd-operator.clusterserviceversion.yaml b/bundle/manifests/argocd-operator.clusterserviceversion.yaml index 8b0f9b67f..f21e476df 100644 --- a/bundle/manifests/argocd-operator.clusterserviceversion.yaml +++ b/bundle/manifests/argocd-operator.clusterserviceversion.yaml @@ -135,7 +135,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/argoproj-labs/argocd-operator support: Argo CD - name: argocd-operator.v0.7.0 + name: argocd-operator.v0.8.0 namespace: placeholder spec: apiservicedefinitions: {} @@ -1050,7 +1050,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - image: quay.io/argoprojlabs/argocd-operator:v0.7.0 + image: quay.io/argoprojlabs/argocd-operator:v0.8.0 livenessProbe: httpGet: path: /healthz @@ -1136,5 +1136,5 @@ spec: maturity: alpha provider: name: Argo CD Community - replaces: argocd-operator.v0.6.0 - version: 0.7.0 + replaces: argocd-operator.v0.7.0 + version: 0.8.0 diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 02a14e419..d9f21e827 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -13,4 +13,4 @@ kind: Kustomization images: - name: controller newName: quay.io/argoprojlabs/argocd-operator - newTag: v0.7.0 + newTag: v0.8.0 diff --git a/config/manifests/bases/argocd-operator.clusterserviceversion.yaml b/config/manifests/bases/argocd-operator.clusterserviceversion.yaml index a8dd45b4c..07a5f0056 100644 --- a/config/manifests/bases/argocd-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/argocd-operator.clusterserviceversion.yaml @@ -725,5 +725,5 @@ spec: maturity: alpha provider: name: Argo CD Community - replaces: argocd-operator.v0.6.0 - version: 0.7.0 + replaces: argocd-operator.v0.7.0 + version: 0.8.0 diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml index 8d1547d9a..0e6f2fc01 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml @@ -1,16 +1,17 @@ apiVersion: v1 +apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: - control-plane: argocd-operator + control-plane: controller-manager name: argocd-operator-controller-manager-metrics-service spec: ports: - name: https port: 8443 - targetPort: 8080 + targetPort: https selector: - control-plane: argocd-operator + control-plane: controller-manager status: - loadBalancer: {} + loadBalancer: {} \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-manager-config_v1_configmap.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-manager-config_v1_configmap.yaml index e04f24437..17374867f 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-manager-config_v1_configmap.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-manager-config_v1_configmap.yaml @@ -14,4 +14,4 @@ data: resourceName: b674928d.argoproj.io kind: ConfigMap metadata: - name: argocd-operator-manager-config + name: argocd-operator-manager-config \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml index 19a68a570..2e6b7dd3a 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -7,4 +7,4 @@ rules: - nonResourceURLs: - /metrics verbs: - - get + - get \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml index 8b0f9b67f..c985631ea 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argocd-operator.v0.7.0.clusterserviceversion.yaml @@ -349,6 +349,38 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Config is the dex connector configuration. + displayName: Configuration + path: dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text - description: GAAnonymizeUsers toggles user IDs being hashed before sending to google analytics. displayName: Google Analytics Anonymize Users' @@ -748,6 +780,17 @@ spec: path: applicationSetController x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Dex is a simple, high-level summary of where the Argo CD Dex + component is in its lifecycle. There are four possible dex values: Pending: + The Argo CD Dex component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Dex component are in a Ready state. + Failed: At least one of the Argo CD Dex component Pods had a failure. Unknown: + The state of the Argo CD Dex component could not be obtained.' + displayName: Dex + path: dex + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text - description: 'NotificationsController is a simple, high-level summary of where the Argo CD notifications controller component is in its lifecycle. There are four possible NotificationsController values: Pending: The Argo CD notifications @@ -805,15 +848,12 @@ spec: path: server x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) - component is in its lifecycle. There are four possible sso values: Pending: - The Argo CD SSO component has been accepted by the Kubernetes system, but - one or more of the required resources have not been created. Running: All - of the required Pods for the Argo CD SSO component are in a Ready state. - Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: - The state of the Argo CD SSO component could not be obtained.' - displayName: SSO - path: sso + - description: 'SSOConfig defines the status of SSO configuration. Success: + Only one SSO provider is configured in CR. Failed: SSO configuration is + illegal or more than one SSO providers are configured in CR. Unknown: The + SSO configuration could not be obtained.' + displayName: SSOConfig + path: ssoConfig x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text version: v1alpha1 @@ -964,7 +1004,6 @@ spec: - monitoring.coreos.com resources: - prometheuses - - prometheusrules - servicemonitors verbs: - '*' @@ -1033,15 +1072,28 @@ spec: replicas: 1 selector: matchLabels: - control-plane: argocd-operator + control-plane: controller-manager strategy: {} template: metadata: labels: - control-plane: argocd-operator + control-plane: controller-manager spec: containers: - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=10 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + resources: {} + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 - --leader-elect command: - /manager @@ -1050,7 +1102,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - image: quay.io/argoprojlabs/argocd-operator:v0.7.0 + image: quay.io/argoprojlabs/argocd-operator@sha256:5541a1c2323016b767f53bcadf696ebd199903d2048f7bd2aee377a332ea5f2c livenessProbe: httpGet: path: /healthz @@ -1137,4 +1189,4 @@ spec: provider: name: Argo CD Community replaces: argocd-operator.v0.6.0 - version: 0.7.0 + version: 0.7.0 \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applications.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applications.yaml index 5a6d15a02..86ef551c2 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applications.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applications.yaml @@ -1428,7 +1428,7 @@ spec: as part of automated sync (default: false)' type: boolean selfHeal: - description: 'SelfHeal specifies whether to revert resources + description: 'SelfHeal specifes whether to revert resources back to their desired state upon modification in the cluster (default: false)' type: boolean @@ -1492,7 +1492,7 @@ spec: conditions items: description: ApplicationCondition contains details about an application - condition, which is usually an error or warning + condition, which is usally an error or warning properties: lastTransitionTime: description: LastTransitionTime is the time the condition was @@ -2941,19 +2941,6 @@ spec: syncResult: description: SyncResult is the result of a Sync operation properties: - managedNamespaceMetadata: - description: ManagedNamespaceMetadata contains the current - sync state of managed namespace metadata - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object resources: description: Resources contains a list of sync result items for each individual resource in a sync operation @@ -4362,4 +4349,4 @@ status: kind: "" plural: "" conditions: null - storedVersions: null + storedVersions: null \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applicationsets.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applicationsets.yaml index 6e2a03d1b..0026e343b 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applicationsets.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_applicationsets.yaml @@ -11581,4 +11581,4 @@ status: kind: "" plural: "" conditions: null - storedVersions: null + storedVersions: null \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_appprojects.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_appprojects.yaml index 8504d6ff0..b4d6c016a 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_appprojects.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_appprojects.yaml @@ -326,4 +326,4 @@ status: kind: "" plural: "" conditions: null - storedVersions: null + storedVersions: null \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocdexports.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocdexports.yaml index 8a8b0b0f1..66cf1aab9 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocdexports.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocdexports.yaml @@ -255,4 +255,4 @@ status: kind: "" plural: "" conditions: [] - storedVersions: [] + storedVersions: [] \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocds.yaml index 87d7c51d6..b6c506753 100644 --- a/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.7.0/argoproj.io_argocds.yaml @@ -537,31 +537,10 @@ spec: description: Sharding contains the options for the Application Controller sharding configuration. properties: - clustersPerShard: - description: ClustersPerShard defines the maximum number of - clusters managed by each argocd shard - format: int32 - minimum: 1 - type: integer - dynamicScalingEnabled: - description: DynamicScalingEnabled defines whether dynamic - scaling should be enabled for Application Controller component - type: boolean enabled: description: Enabled defines whether sharding should be enabled on the Application Controller component. type: boolean - maxShards: - description: MaxShards defines the maximum number of shards - at any given point - format: int32 - type: integer - minShards: - description: MinShards defines the minimum number of shards - at any given point - format: int32 - minimum: 1 - type: integer replicas: description: Replicas defines the number of replicas to run in the Application controller shard. @@ -569,6 +548,56 @@ spec: type: integer type: object type: object + dex: + description: Dex defines the Dex server options for ArgoCD. + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must be a + member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object disableAdmin: description: DisableAdmin will disable the admin user. type: boolean @@ -6172,6 +6201,9 @@ spec: description: Version is the Dex container image tag. type: string type: object + image: + description: Image is the SSO container image. + type: string keycloak: description: Keycloak contains the configuration for Argo CD keycloak authentication @@ -6222,6 +6254,39 @@ spec: description: Provider installs and configures the given SSO Provider with Argo CD. type: string + resources: + description: Resources defines the Compute Resources required + by the container for SSO. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the SSO container image tag. + type: string type: object statusBadgeEnabled: description: StatusBadgeEnabled toggles application status badge feature. @@ -6285,6 +6350,16 @@ spec: component Pods had a failure. Unknown: The state of the Argo CD applicationSet controller component could not be obtained.' type: string + dex: + description: 'Dex is a simple, high-level summary of where the Argo + CD Dex component is in its lifecycle. There are four possible dex + values: Pending: The Argo CD Dex component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Dex component are in a Ready state. Failed: At least one + of the Argo CD Dex component Pods had a failure. Unknown: The state + of the Argo CD Dex component could not be obtained.' + type: string host: description: Host is the hostname of the Ingress. type: string @@ -6349,15 +6424,11 @@ spec: one of the Argo CD server component Pods had a failure. Unknown: The state of the Argo CD server component could not be obtained.' type: string - sso: - description: 'SSO is a simple, high-level summary of where the Argo - CD SSO(Dex/Keycloak) component is in its lifecycle. There are four - possible sso values: Pending: The Argo CD SSO component has been - accepted by the Kubernetes system, but one or more of the required - resources have not been created. Running: All of the required Pods - for the Argo CD SSO component are in a Ready state. Failed: At least - one of the Argo CD SSO component Pods had a failure. Unknown: The - state of the Argo CD SSO component could not be obtained.' + ssoConfig: + description: 'SSOConfig defines the status of SSO configuration. Success: + Only one SSO provider is configured in CR. Failed: SSO configuration + is illegal or more than one SSO providers are configured in CR. + Unknown: The SSO configuration could not be obtained.' type: string type: object type: object @@ -6370,4 +6441,4 @@ status: kind: "" plural: "" conditions: [] - storedVersions: [] + storedVersions: [] \ No newline at end of file diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml new file mode 100644 index 000000000..8d1547d9a --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + control-plane: argocd-operator + name: argocd-operator-controller-manager-metrics-service +spec: + ports: + - name: https + port: 8443 + targetPort: 8080 + selector: + control-plane: argocd-operator +status: + loadBalancer: {} diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-manager-config_v1_configmap.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-manager-config_v1_configmap.yaml new file mode 100644 index 000000000..e04f24437 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-manager-config_v1_configmap.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +data: + controller_manager_config.yaml: | + apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 + kind: ControllerManagerConfig + health: + healthProbeBindAddress: :8081 + metrics: + bindAddress: 127.0.0.1:8080 + webhook: + port: 9443 + leaderElection: + leaderElect: true + resourceName: b674928d.argoproj.io +kind: ConfigMap +metadata: + name: argocd-operator-manager-config diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 000000000..19a68a570 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: argocd-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml new file mode 100644 index 000000000..f21e476df --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml @@ -0,0 +1,1140 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "AppProject", + "metadata": { + "name": "example" + }, + "spec": null + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "Application", + "metadata": { + "name": "example" + }, + "spec": null + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "ApplicationSet", + "metadata": { + "name": "example" + }, + "spec": null + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "ArgoCD", + "metadata": { + "name": "argocd-sample" + }, + "spec": { + "controller": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "2048Mi" + }, + "requests": { + "cpu": "250m", + "memory": "1024Mi" + } + } + }, + "ha": { + "enabled": false, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "redis": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "repo": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "512Mi" + }, + "requests": { + "cpu": "250m", + "memory": "256Mi" + } + } + }, + "server": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "125m", + "memory": "128Mi" + } + }, + "route": { + "enabled": true + } + }, + "sso": { + "dex": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "provider": "dex" + } + } + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "ArgoCDExport", + "metadata": { + "name": "argocdexport-sample" + }, + "spec": { + "argocd": "argocd-sample" + } + } + ] + capabilities: Deep Insights + categories: Integration & Delivery + certified: "false" + description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. + operators.operatorframework.io/builder: operator-sdk-v1.10.0+git + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + repository: https://github.com/argoproj-labs/argocd-operator + support: Argo CD + name: argocd-operator.v0.8.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: An Application is a group of Kubernetes resources as defined by + a manifest. + displayName: Application + kind: Application + name: applications.argoproj.io + version: v1alpha1 + - description: An ApplicationSet is a group or set of Application resources. + displayName: ApplicationSet + kind: ApplicationSet + name: applicationsets.argoproj.io + version: v1alpha1 + - description: An AppProject is a logical grouping of Argo CD Applications. + displayName: AppProject + kind: AppProject + name: appprojects.argoproj.io + version: v1alpha1 + - description: ArgoCDExport is the Schema for the argocdexports API + displayName: Argo CDExport + kind: ArgoCDExport + name: argocdexports.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1alpha1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: Argocd is the name of the ArgoCD instance to export. + displayName: ArgoCD + path: argocd + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + displayName: Schedule + path: schedule + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Storage defines the storage configuration options. + displayName: Storage + path: storage + statusDescriptors: + - description: 'Phase is a simple, high-level summary of where the ArgoCDExport + is in its lifecycle. There are five possible phase values: Pending: The + ArgoCDExport has been accepted by the Kubernetes system, but one or more + of the required resources have not been created. Running: All of the containers + for the ArgoCDExport are still running, or in the process of starting or + restarting. Succeeded: All containers for the ArgoCDExport have terminated + in success, and will not be restarted. Failed: At least one container has + terminated in failure, either exited with non-zero status or was terminated + by the system. Unknown: For some reason the state of the ArgoCDExport could + not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1alpha1 + - description: ArgoCD is the Schema for the argocds API + displayName: Argo CD + kind: ArgoCD + name: argocds.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1alpha1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: ApplicationInstanceLabelKey is the key name where Argo CD injects + the app name as a tracking label. + displayName: Application Instance Label Key' + path: applicationInstanceLabelKey + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: applicationSet.webhookServer.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: applicationSet.webhookServer.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: applicationSet.webhookServer.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ConfigManagementPlugins is used to specify additional config + management plugins. + displayName: Config Management Plugins' + path: configManagementPlugins + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Operation is the number of application operation processors. + displayName: Operation Processor Count' + path: controller.processors.operation + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Status is the number of application status processors. + displayName: Status Processor Count' + path: controller.processors.status + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resources defines the Compute Resources required by the container + for the Application Controller. + displayName: Resource Requirements' + path: controller.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: GAAnonymizeUsers toggles user IDs being hashed before sending + to google analytics. + displayName: Google Analytics Anonymize Users' + path: gaAnonymizeUsers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: GATrackingID is the google analytics tracking ID to use. + displayName: Google Analytics Tracking ID' + path: gaTrackingID + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Grafana support globally for ArgoCD. + displayName: Enabled + path: grafana.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: grafana.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Grafana container image. + displayName: Image + path: grafana.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: grafana.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Grafana. + displayName: Resource Requirements' + path: grafana.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: grafana.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Grafana Deployment. + displayName: Size + path: grafana.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Version is the Grafana container image tag. + displayName: Version + path: grafana.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle HA support globally for Argo CD. + displayName: Enabled + path: ha.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: HelpChatText is the text for getting chat help, defaults to "Chat + now!" + displayName: Help Chat Text' + path: helpChatText + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: HelpChatURL is the URL for getting chat help, this will typically + be your Slack channel for support. + displayName: Help Chat URL' + path: helpChatURL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Image is the ArgoCD container image for all ArgoCD components. + displayName: Image + path: image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of an ArgoCDExport from which to import data. + displayName: Name + path: import.name + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: Namespace for the ArgoCDExport, defaults to the same namespace + as the ArgoCD. + displayName: Namespace + path: import.namespace + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: InitialRepositories to configure Argo CD with upon creation of + the cluster. + displayName: Initial Repositories' + path: initialRepositories + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: KustomizeVersions is a listing of configured versions of Kustomize + to be made available within ArgoCD. + displayName: Kustomize Build Options' + path: kustomizeVersions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: OIDCConfig is the OIDC configuration as an alternative to dex. + displayName: OIDC Config' + path: oidcConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Prometheus support globally for ArgoCD. + displayName: Enabled + path: prometheus.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: prometheus.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: prometheus.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: prometheus.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Prometheus StatefulSet. + displayName: Size + path: prometheus.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: DefaultPolicy is the name of the default role which Argo CD will + falls back to, when authorizing API requests (optional). If omitted or empty, + users may be still be able to login, but will see no apps, projects, etc... + displayName: Default Policy' + path: rbac.defaultPolicy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Policy is CSV containing user-defined RBAC policies and role + definitions. Policy rules are in the form: p, subject, resource, action, + object, effect Role definitions and bindings are in the form: g, subject, + inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + displayName: Policy + path: rbac.policy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Scopes controls which OIDC scopes to examine during rbac enforcement + (in addition to `sub` scope). If omitted, defaults to: ''[groups]''.' + displayName: Scopes + path: rbac.scopes + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Redis container image. + displayName: Image + path: redis.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: redis.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Redis container image tag. + displayName: Version + path: redis.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: repo.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: ResourceActions customizes resource action behavior. + displayName: Resource Action Customizations' + path: resourceActions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'ResourceCustomizations customizes resource behavior. Keys are + in the form: group/Kind. Please note that this is being deprecated in favor + of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + displayName: Resource Customizations' + path: resourceCustomizations + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceExclusions is used to completely ignore entire classes + of resource group/kinds. + displayName: Resource Exclusions' + path: resourceExclusions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceHealthChecks customizes resource health check behavior. + displayName: Resource Health Check Customizations' + path: resourceHealthChecks + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceIgnoreDifferences customizes resource ignore difference + behavior. + displayName: Resource Ignore Difference Customizations' + path: resourceIgnoreDifferences + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceTrackingMethod defines how Argo CD should track resources + that it manages + displayName: Resource Tracking Method' + path: resourceTrackingMethod + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle autoscaling support for the Argo CD Server + component. + displayName: Autoscale Enabled' + path: server.autoscale.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: GRPC Host + path: server.grpc.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Ingress defines the desired state for the Argo CD Server GRPC + Ingress. + displayName: GRPC Ingress Enabled' + path: server.grpc.ingress + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.grpc.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: server.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Insecure toggles the insecure flag. + displayName: Insecure + path: server.insecure + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for the Argo CD server component. + displayName: Resource Requirements' + path: server.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: server.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Type is the ServiceType to use for the Service resource. + displayName: Service Type' + path: server.service.type + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Config is the dex connector configuration. + displayName: Configuration + path: sso.dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: sso.dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: sso.dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: sso.dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: sso.dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: StatusBadgeEnabled toggles application status badge feature. + displayName: Status Badge Enabled' + path: statusBadgeEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: UsersAnonymousEnabled toggles anonymous user access. The anonymous + users get default role permissions specified argocd-rbac-cm. + displayName: Anonymous Users Enabled' + path: usersAnonymousEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Version is the tag to use with the ArgoCD container image for + all ArgoCD components. + displayName: Version + path: version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + statusDescriptors: + - description: 'ApplicationController is a simple, high-level summary of where + the Argo CD application controller component is in its lifecycle. There + are four possible ApplicationController values: Pending: The Argo CD application + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD application controller component are in + a Ready state. Failed: At least one of the Argo CD application controller + component Pods had a failure. Unknown: The state of the Argo CD application + controller component could not be obtained.' + displayName: ApplicationController + path: applicationController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'ApplicationSetController is a simple, high-level summary of + where the Argo CD applicationSet controller component is in its lifecycle. + There are four possible ApplicationSetController values: Pending: The Argo + CD applicationSet controller component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD applicationSet controller + component are in a Ready state. Failed: At least one of the Argo CD applicationSet + controller component Pods had a failure. Unknown: The state of the Argo + CD applicationSet controller component could not be obtained.' + displayName: ApplicationSetController + path: applicationSetController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'NotificationsController is a simple, high-level summary of where + the Argo CD notifications controller component is in its lifecycle. There + are four possible NotificationsController values: Pending: The Argo CD notifications + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD notifications controller component are + in a Ready state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD notifications + controller component could not be obtained.' + displayName: NotificationsController + path: notificationsController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Phase is a simple, high-level summary of where the ArgoCD is + in its lifecycle. There are four possible phase values: Pending: The ArgoCD + has been accepted by the Kubernetes system, but one or more of the required + resources have not been created. Available: All of the resources for the + ArgoCD are ready. Failed: At least one resource has experienced a failure. + Unknown: The state of the ArgoCD phase could not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Redis is a simple, high-level summary of where the Argo CD Redis + component is in its lifecycle. There are four possible redis values: Pending: + The Argo CD Redis component has been accepted by the Kubernetes system, + but one or more of the required resources have not been created. Running: + All of the required Pods for the Argo CD Redis component are in a Ready + state. Failed: At least one of the Argo CD Redis component Pods had a failure. + Unknown: The state of the Argo CD Redis component could not be obtained.' + displayName: Redis + path: redis + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Repo is a simple, high-level summary of where the Argo CD Repo + component is in its lifecycle. There are four possible repo values: Pending: + The Argo CD Repo component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Repo component are in a Ready state. + Failed: At least one of the Argo CD Repo component Pods had a failure. + Unknown: The state of the Argo CD Repo component could not be obtained.' + displayName: Repo + path: repo + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Server is a simple, high-level summary of where the Argo CD + server component is in its lifecycle. There are four possible server values: + Pending: The Argo CD server component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD server component are in + a Ready state. Failed: At least one of the Argo CD server component Pods + had a failure. Unknown: The state of the Argo CD server component could + not be obtained.' + displayName: Server + path: server + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) + component is in its lifecycle. There are four possible sso values: Pending: + The Argo CD SSO component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD SSO component are in a Ready state. + Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: + The state of the Argo CD SSO component could not be obtained.' + displayName: SSO + path: sso + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1alpha1 + description: | + ## Overview + + The Argo CD Operator manages the full lifecycle for [Argo CD](https://argoproj.github.io/argo-cd/) and it's + components. The operator's goal is to automate the tasks required when operating an Argo CD cluster. + + Beyond installation, the operator helps to automate the process of upgrading, backing up and restoring as needed and + remove the human as much as possible. In addition, the operator aims to provide deep insights into the Argo CD + environment by configuring Prometheus and Grafana to aggregate, visualize and expose the metrics already exported by + Argo CD. + + The operator aims to provide the following, and is a work in progress. + + * Easy configuration and installation of the Argo CD components with sane defaults to get up and running quickly. + * Provide seamless upgrades to the Argo CD components. + * Ability to back up and restore an Argo CD cluster from a point in time or on a recurring schedule. + * Aggregate and expose the metrics for Argo CD and the operator itself using Prometheus and Grafana. + * Autoscale the Argo CD components as necessary to handle variability in demand. + + ## Usage + + Deploy a basic Argo CD cluster by creating a new ArgoCD resource in the namespace where the operator is installed. + + ``` + apiVersion: argoproj.io/v1alpha1 + kind: ArgoCD + metadata: + name: example-argocd + spec: {} + ``` + + ## Backup + + Backup the cluster above by creating a new ArgoCDExport resource in the namespace where the operator is installed. + + ``` + apiVersion: argoproj.io/v1alpha1 + kind: ArgoCDExport + metadata: + name: example-argocdexport + spec: + argocd: example-argocd + ``` + + See the [documentation](https://argocd-operator.readthedocs.io) and examples on + [github](https://github.com/argoproj-labs/argocd-operator) for more information. + displayName: Argo CD + icon: + - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+Cjxzdmcgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDIzIDMwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MjsiPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMSwwLDAsMSwtOS4yLC03KSI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2LDI3LjdDMTYsMjcuNyAxNS44LDI4LjMgMTUuNSwyOC42QzE1LjMsMjguOCAxNS4xLDI4LjkgMTQuOCwyOC45QzE0LjEsMjkuMSAxMy4zLDI5LjIgMTMuMywyOS4yQzEzLjMsMjkuMiAxNCwyOS4zIDE0LjgsMjkuNEMxNS4xLDI5LjQgMTUuMSwyOS40IDE1LjMsMjkuNUMxNS44LDI5LjUgMTYsMjkuMiAxNiwyOS4yTDE2LDI3LjdaIiBzdHlsZT0iZmlsbDpyZ2IoMjMzLDEwMSw3NSk7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuMiwyNy43QzI1LjIsMjcuNyAyNS40LDI4LjMgMjUuNywyOC42QzI1LjksMjguOCAyNi4xLDI4LjkgMjYuNCwyOC45QzI3LjEsMjkuMSAyNy45LDI5LjIgMjcuOSwyOS4yQzI3LjksMjkuMiAyNy4yLDI5LjMgMjYuMywyOS40QzI2LDI5LjQgMjYsMjkuNCAyNS44LDI5LjVDMjUuMiwyOS41IDI1LjEsMjkuMiAyNS4xLDI5LjJMMjUuMiwyNy43WiIgc3R5bGU9ImZpbGw6cmdiKDIzMywxMDEsNzUpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMjAuNyIgY3k9IjE3LjgiIHI9IjEwLjgiIHN0eWxlPSJmaWxsOnJnYigxODIsMjA3LDIzNCk7Ii8+CiAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIyMC43IiBjeT0iMTcuOCIgcj0iMTAuNCIgc3R5bGU9ImZpbGw6cmdiKDIzMCwyNDUsMjQ4KTsiLz4KICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9IjIwLjciIGN5PSIxOCIgcj0iOC41IiBzdHlsZT0iZmlsbDpyZ2IoMjA4LDIzMiwyNDApOyIvPgogICAgICAgICAgICAgICAgPGcgaWQ9IkJvZHlfMV8iPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNS43LDIyQzE1LjcsMjIgMTYuNCwzMy4zIDE2LjQsMzMuNUMxNi40LDMzLjYgMTYuNSwzMy44IDE2LDM0QzE1LjUsMzQuMiAxMy45LDM0LjYgMTMuOSwzNC42TDE2LjMsMzQuNkMxNy40LDM0LjYgMTcuNCwzMy43IDE3LjQsMzMuNUMxNy40LDMzLjMgMTcuNywyOSAxNy43LDI5QzE3LjcsMjkgMTcuOCwzNC4xIDE3LjgsMzQuM0MxNy44LDM0LjUgMTcuNywzNC44IDE3LDM1QzE2LjUsMzUuMSAxNSwzNS40IDE1LDM1LjRMMTcuMywzNS40QzE4LjcsMzUuNCAxOC43LDM0LjUgMTguNywzNC41TDE5LDMwQzE5LDMwIDE5LjEsMzQuNSAxOS4xLDM1QzE5LjEsMzUuNCAxOC44LDM1LjcgMTcuNywzNS45QzE3LDM2LjEgMTYuMSwzNi4zIDE2LjEsMzYuM0wxOC43LDM2LjNDMjAsMzYuMiAyMC4yLDM1LjMgMjAuMiwzNS4zTDIyLjQsMjQuMUwxNS43LDIyWiIgc3R5bGU9ImZpbGw6cmdiKDIzOCwxMjEsNzUpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yNS43LDIyQzI1LjcsMjIgMjUsMzMuMyAyNSwzMy41QzI1LDMzLjYgMjQuOSwzMy44IDI1LjQsMzRDMjUuOSwzNC4yIDI3LjUsMzQuNiAyNy41LDM0LjZMMjUuMSwzNC42QzI0LDM0LjYgMjQsMzMuNyAyNCwzMy41QzI0LDMzLjMgMjMuNywyOSAyMy43LDI5QzIzLjcsMjkgMjMuNiwzNC4xIDIzLjYsMzQuM0MyMy42LDM0LjUgMjMuNywzNC44IDI0LjQsMzVDMjQuOSwzNS4xIDI2LjQsMzUuNCAyNi40LDM1LjRMMjQuMSwzNS40QzIyLjcsMzUuNCAyMi43LDM0LjUgMjIuNywzNC41TDIyLjQsMzBDMjIuNCwzMCAyMi4zLDM0LjUgMjIuMywzNUMyMi4zLDM1LjQgMjIuNiwzNS43IDIzLjcsMzUuOUMyNC40LDM2LjEgMjUuMywzNi4zIDI1LjMsMzYuM0wyMi43LDM2LjNDMjEuNCwzNi4yIDIxLjIsMzUuMyAyMS4yLDM1LjNMMTksMjQuMUwyNS43LDIyWiIgc3R5bGU9ImZpbGw6cmdiKDIzOCwxMjEsNzUpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yNS44LDE2LjVDMjUuOCwxOS4zIDIzLjUsMjEuNSAyMC44LDIxLjVDMTguMSwyMS41IDE1LjgsMTkuMiAxNS44LDE2LjVDMTUuOCwxMy44IDE4LjEsMTEuNSAyMC44LDExLjVDMjMuNSwxMS41IDI1LjgsMTMuNyAyNS44LDE2LjVaIiBzdHlsZT0iZmlsbDpyZ2IoMjM4LDEyMSw3NSk7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICAgICAgPGNsaXBQYXRoIGlkPSJfY2xpcDEiPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuOCwxNi4zTDI1LjIsMzBMMTYuMiwzMEwxNS43LDE2LjMiLz4KICAgICAgICAgICAgICAgICAgICA8L2NsaXBQYXRoPgogICAgICAgICAgICAgICAgICAgIDxnIGNsaXAtcGF0aD0idXJsKCNfY2xpcDEpIj4KICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMjAuOCIgY3k9IjE5LjIiIHI9IjguOSIgc3R5bGU9ImZpbGw6cmdiKDIzOCwxMjEsNzUpOyIvPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuNSwyMkMyNS41LDIyIDI2LjEsMTYuNyAyNS4zLDE0LjdDMjMuOCwxMS4yIDIwLjMsMTEuNSAyMC4zLDExLjVDMjAuMywxMS41IDIyLjMsMTIuMyAyMi40LDE1LjNDMjIuNSwxNy40IDIyLjQsMjAuNSAyMi40LDIwLjVMMjUuNSwyMloiIHN0eWxlPSJmaWxsOnJnYigyMjcsNzgsNTkpO2ZpbGwtb3BhY2l0eTowLjIyO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPGcgaWQ9IkZhY2VfMV8iPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9IjE4LjciIGN5PSIxMy44IiByPSIwLjciIHN0eWxlPSJmaWxsOnJnYigyNTEsMjIzLDE5NSk7ZmlsbC1vcGFjaXR5OjAuNTsiLz4KICAgICAgICAgICAgICAgICAgICA8Zz4KICAgICAgICAgICAgICAgICAgICAgICAgPGc+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjIuNSwyNEMyMi41LDI1LjcgMjEuNywyNi44IDIwLjcsMjYuOEMxOS43LDI2LjggMTguOSwyNS41IDE4LjksMjMuOEMxOC45LDIzLjggMTkuNywyNS40IDIwLjgsMjUuNEMyMS45LDI1LjQgMjIuNSwyNCAyMi41LDI0WiIgc3R5bGU9ImZpbGw6cmdiKDEsMSwxKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMi41LDI0QzIyLjUsMjUuMSAyMS43LDI1LjcgMjAuNywyNS43QzE5LjcsMjUuNyAxOSwyNC45IDE5LDIzLjlDMTksMjMuOSAxOS44LDI0LjkgMjAuOSwyNC45QzIyLDI0LjkgMjIuNSwyNCAyMi41LDI0WiIgc3R5bGU9ImZpbGw6d2hpdGU7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgPGc+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Zz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Zz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMjQuMiIgY3k9IjE5LjMiIHI9IjMuMSIgc3R5bGU9ImZpbGw6cmdiKDIzMywxMDEsNzUpOyIvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIxNy4yIiBjeT0iMTkuMyIgcj0iMy4xIiBzdHlsZT0iZmlsbDpyZ2IoMjMzLDEwMSw3NSk7Ii8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIyNC4yIiBjeT0iMTkuMyIgcj0iMi40IiBzdHlsZT0iZmlsbDp3aGl0ZTsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMTciIGN5PSIxOS4zIiByPSIyLjQiIHN0eWxlPSJmaWxsOndoaXRlOyIvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9IjE3IiBjeT0iMTkiIHI9IjAuNyIgc3R5bGU9ImZpbGw6cmdiKDEsMSwxKTsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIyNC4yIiBjeT0iMTkiIHI9IjAuNyIgc3R5bGU9ImZpbGw6cmdiKDEsMSwxKTsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik05LjcsMjAuNUM5LjQsMjAuNSA5LjIsMjAuMyA5LjIsMjBMOS4yLDE2QzkuMiwxNS43IDkuNCwxNS41IDkuNywxNS41QzEwLDE1LjUgMTAuMiwxNS43IDEwLjIsMTZMMTAuMiwyMEMxMC4yLDIwLjMgMTAsMjAuNSA5LjcsMjAuNVoiIHN0eWxlPSJmaWxsOnJnYigxODIsMjA3LDIzNCk7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMzEuNSwyMC41QzMxLjIsMjAuNSAzMSwyMC4zIDMxLDIwTDMxLDE2QzMxLDE1LjcgMzEuMiwxNS41IDMxLjUsMTUuNUMzMS44LDE1LjUgMzIsMTUuNyAzMiwxNkwzMiwyMEMzMiwyMC4zIDMxLjgsMjAuNSAzMS41LDIwLjVaIiBzdHlsZT0iZmlsbDpyZ2IoMTgyLDIwNywyMzQpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMTcuMyIgY3k9IjkuOCIgcj0iMC41IiBzdHlsZT0iZmlsbDp3aGl0ZTsiLz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMy43LDIzLjNDMTMuNiwyMy4zIDEzLjUsMjMuMyAxMy40LDIzLjJDMTIuMiwyMS43IDExLjYsMTkuOCAxMS42LDE3LjlDMTEuNiwxNi4zIDEyLDE0LjggMTIuOCwxMy40QzEzLjYsMTIuMSAxNC43LDExIDE2LDEwLjJDMTYuMiwxMC4xIDE2LjQsMTAuMiAxNi41LDEwLjNDMTYuNiwxMC41IDE2LjUsMTAuNyAxNi40LDEwLjhDMTMuOSwxMi4yIDEyLjMsMTQuOSAxMi4zLDE3LjhDMTIuMywxOS42IDEyLjksMjEuMyAxNCwyMi43QzE0LjEsMjIuOCAxNC4xLDIzLjEgMTMuOSwyMy4yQzEzLjgsMjMuMyAxMy44LDIzLjMgMTMuNywyMy4zWiIgc3R5bGU9ImZpbGw6d2hpdGU7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuMiwyOEwyNS4yLDI3LjJDMjMuOCwyOCAyMi4zLDI4LjggMjAuNSwyOC44QzE4LjUsMjguOCAxNy4yLDI3LjkgMTUuOSwyNy4yTDE2LDI4QzE2LDI4IDE3LjUsMjkuNiAyMC42LDI5LjZDMjMuNSwyOS41IDI1LjIsMjggMjUuMiwyOFoiIHN0eWxlPSJmaWxsOnJnYigyMzMsMTAxLDc1KTtmaWxsLW9wYWNpdHk6MC4yNTtmaWxsLXJ1bGU6bm9uemVybzsiLz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg== + mediatype: image/svg+xml + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - events + - namespaces + - persistentvolumeclaims + - pods + - secrets + - serviceaccounts + - services + - services/finalizers + verbs: + - '*' + - apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - get + - apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - '*' + - apiGroups: + - apps + resourceNames: + - argocd-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - apps.openshift.io + resources: + - deploymentconfigs + verbs: + - '*' + - apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - '*' + - apiGroups: + - argoproj.io + resources: + - argocdexports + - argocdexports/finalizers + - argocdexports/status + verbs: + - '*' + - apiGroups: + - argoproj.io + resources: + - argocds + - argocds/finalizers + - argocds/status + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - '*' + - apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - '*' + - apiGroups: + - config.openshift.io + resources: + - clusterversions + verbs: + - get + - list + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - prometheuses + - prometheusrules + - servicemonitors + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - '*' + - apiGroups: + - oauth.openshift.io + resources: + - oauthclients + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - '*' + - apiGroups: + - template.openshift.io + resources: + - templateconfigs + - templateinstances + - templates + verbs: + - '*' + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: argocd-operator-controller-manager + deployments: + - name: argocd-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + control-plane: argocd-operator + strategy: {} + template: + metadata: + labels: + control-plane: argocd-operator + spec: + containers: + - args: + - --leader-elect + command: + - /manager + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + image: quay.io/argoprojlabs/argocd-operator:v0.8.0 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + securityContext: + runAsNonRoot: true + serviceAccountName: argocd-operator-controller-manager + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: argocd-operator-controller-manager + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - gitops + - kubernetes + links: + - name: Argo CD Project + url: https://argoproj.github.io/argo-cd/ + - name: Operator Documentation + url: https://argocd-operator.readthedocs.io + - name: Operator Source Code + url: https://github.com/argoproj-labs/argocd-operator + maintainers: + - email: aveerama@redhat.com + name: Abhishek Veeramalla + maturity: alpha + provider: + name: Argo CD Community + replaces: argocd-operator.v0.7.0 + version: 0.8.0 diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml new file mode 100644 index 000000000..5a6d15a02 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml @@ -0,0 +1,4365 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: applications.argoproj.io + app.kubernetes.io/part-of: argocd + name: applications.argoproj.io +spec: + group: argoproj.io + names: + kind: Application + listKind: ApplicationList + plural: applications + shortNames: + - app + - apps + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.sync.status + name: Sync Status + type: string + - jsonPath: .status.health.status + name: Health Status + type: string + - jsonPath: .status.sync.revision + name: Revision + priority: 10 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Application is a definition of Application resource. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + operation: + description: Operation contains information about a requested or running + operation + properties: + info: + description: Info is a list of informational items for this operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent retries + of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default unit + is seconds, but could also be a duration (e.g. "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time allowed + for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + dryRun: + description: DryRun specifies to perform a `kubectl apply --dry-run` + without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides sync + source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from the cluster + that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall be part + of the sync + items: + description: SyncOperationResource contains resources to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: Revision is the revision (Git) or chart version (Helm) + which to sync the application to If omitted, will use the revision + specified in app spec. + type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array + source: + description: Source overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by + not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources for + Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be + commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. + properties: + destination: + description: Destination is a reference to the target Kubernetes server + and namespace + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster and + must be set to the Kubernetes control plane API + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison + items: + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted managers. + Fields mutated by those managers will take precedence over + the desired state defined in the SCM and won't be displayed + in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: Project is a reference to the project this application + belongs to. The empty string means that application belongs to the + 'default' project. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit limits the number of items kept + in the application's revision history, which is used for informational + purposes as well as for rollbacks to previous versions. This should + only be changed in exceptional circumstances. Setting to zero will + store no history. This will reduce storage used. Increasing will + increase the space used to store the history, so we do not recommend + increasing it. Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether to + apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize adds + to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifies whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usually an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + health: + description: Health contains information about the application's current + health status + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory + format: int64 + type: integer + revision: + description: Revision holds the revision the sync was performed + against + type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array + source: + description: Source is a reference to the application source + used for the sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - deployedAt + - id + type: object + type: array + observedAt: + description: 'ObservedAt indicates when the application state was + updated without querying latest git state Deprecated: controller + no longer updates ObservedAt field' + format: date-time + type: string + operationState: + description: OperationState contains information about any ongoing + operations, such as a sync + properties: + finishedAt: + description: FinishedAt contains time of operation completion + format: date-time + type: string + message: + description: Message holds any pertinent messages when attempting + to perform operation (typically errors). + type: string + operation: + description: Operation is the original requested operation + properties: + info: + description: Info is a list of informational items for this + operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was + initiated automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who + started operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync + fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base + duration after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of + time allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for + retrying a failed sync. If set to 0, no retries will + be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + dryRun: + description: DryRun specifies to perform a `kubectl apply + --dry-run` without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides + sync source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from + the cluster that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall + be part of the sync + items: + description: SyncOperationResource contains resources + to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: Revision is the revision (Git) or chart version + (Helm) which to sync the application to If omitted, + will use the revision specified in app spec. + type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array + source: + description: Source overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to + Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles do + not exist locally by not appending them to helm + template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of + Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in + the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block + type: string + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize + Replicas override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, + e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the + sync + properties: + apply: + description: Apply will perform a `kubectl apply` + to perform the sync. + properties: + force: + description: Force indicates whether or not to + supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, + when PATCH encounters conflict and has retried + for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources + to perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to + supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, + when PATCH encounters conflict and has retried + for 5 times. + type: boolean + type: object + type: object + type: object + type: object + phase: + description: Phase is the current phase of the operation + type: string + retryCount: + description: RetryCount contains time of operation retries + format: int64 + type: integer + startedAt: + description: StartedAt contains time of operation start + format: date-time + type: string + syncResult: + description: SyncResult is the result of a Sync operation + properties: + managedNamespaceMetadata: + description: ManagedNamespaceMetadata contains the current + sync state of managed namespace metadata + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + resources: + description: Resources contains a list of sync result items + for each individual resource in a sync operation + items: + description: ResourceResult holds the operation result details + of a specific resource + properties: + group: + description: Group specifies the API group of the resource + type: string + hookPhase: + description: HookPhase contains the state of any operation + associated with this resource OR hook This can also + contain values for non-hook resources. + type: string + hookType: + description: HookType specifies the type of the hook. + Empty for non-hook resources + type: string + kind: + description: Kind specifies the API kind of the resource + type: string + message: + description: Message contains an informational or error + message for the last sync OR operation + type: string + name: + description: Name specifies the name of the resource + type: string + namespace: + description: Namespace specifies the target namespace + of the resource + type: string + status: + description: Status holds the final result of the sync. + Will be empty if the resources is yet to be applied/pruned + and is always zero-value for hooks + type: string + syncPhase: + description: SyncPhase indicates the particular phase + of the sync that this result was acquired in + type: string + version: + description: Version specifies the API version of the + resource + type: string + required: + - group + - kind + - name + - namespace + - version + type: object + type: array + revision: + description: Revision holds the revision this sync operation + was performed to + type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array + source: + description: Source records the application source information + of the sync, used for comparing auto-sync + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - revision + type: object + required: + - operation + - phase + - startedAt + type: object + reconciledAt: + description: ReconciledAt indicates when the application state was + reconciled using the latest git version + format: date-time + type: string + resourceHealthSource: + description: 'ResourceHealthSource indicates where the resource health + status is stored: inline if not set or appTree' + type: string + resources: + description: Resources is a list of Kubernetes resources managed by + this application + items: + description: 'ResourceStatus holds the current sync and health status + of a resource TODO: describe members of this type' + properties: + group: + type: string + health: + description: HealthStatus contains information about the currently + observed health state of an application or resource + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application + or resource + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresPruning: + type: boolean + status: + description: SyncStatusCode is a type which represents possible + comparison results + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + sourceType: + description: SourceType specifies the type of this application + type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array + summary: + description: Summary contains a list of URLs and container images + used by this application + properties: + externalURLs: + description: ExternalURLs holds all external URLs of application + child resources. + items: + type: string + type: array + images: + description: Images holds all images of application child resources. + items: + type: string + type: array + type: object + sync: + description: Sync contains information about the application's current + sync status + properties: + comparedTo: + description: ComparedTo contains information about what has been + compared + properties: + destination: + description: Destination is a reference to the application's + destination used for comparison + properties: + name: + description: Name is an alternate way of specifying the + target cluster by its symbolic name + type: string + namespace: + description: Namespace specifies the target namespace + for the application's resources. The namespace will + only be set for namespace-scoped resources that have + not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster + and must be set to the Kubernetes control plane API + type: string + type: object + source: + description: Source is a reference to the application's source + used for comparison + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - destination + type: object + revision: + description: Revision contains information about the revision + the comparison has been performed to + type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array + status: + description: Status is the sync state of the comparison + type: string + required: + - status + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml new file mode 100644 index 000000000..6e2a03d1b --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml @@ -0,0 +1,11584 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: applicationsets.argoproj.io + app.kubernetes.io/part-of: argocd + name: applicationsets.argoproj.io +spec: + group: argoproj.io + names: + kind: ApplicationSet + listKind: ApplicationSetList + plural: applicationsets + shortNames: + - appset + - appsets + singular: applicationset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + pullRequest: + properties: + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + pullRequest: + properties: + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + pullRequest: + properties: + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + goTemplate: + type: boolean + preservedFields: + properties: + annotations: + items: + type: string + type: array + type: object + strategy: + properties: + rollingSync: + properties: + steps: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + maxUpdate: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: + type: string + type: object + syncPolicy: + properties: + preserveResourcesOnDeletion: + type: boolean + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - template + type: object + status: + properties: + applicationStatus: + items: + properties: + application: + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + step: + type: string + required: + - application + - message + - status + - step + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_appprojects.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_appprojects.yaml new file mode 100644 index 000000000..8504d6ff0 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_appprojects.yaml @@ -0,0 +1,329 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: appprojects.argoproj.io + app.kubernetes.io/part-of: argocd + name: appprojects.argoproj.io +spec: + group: argoproj.io + names: + kind: AppProject + listKind: AppProjectList + plural: appprojects + shortNames: + - appproj + - appprojs + singular: appproject + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'AppProject provides a logical grouping of applications, providing + controls for: * where the apps may deploy to (cluster whitelist) * what + may be deployed (repository whitelist, resource whitelist/blacklist) * who + can access these applications (roles, OIDC group claims bindings) * and + what they can do (RBAC policies) * automation access to these roles (JWT + tokens)' + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AppProjectSpec is the specification of an AppProject + properties: + clusterResourceBlacklist: + description: ClusterResourceBlacklist contains list of blacklisted + cluster level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + clusterResourceWhitelist: + description: ClusterResourceWhitelist contains list of whitelisted + cluster level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + description: + description: Description contains optional project description + type: string + destinations: + description: Destinations contains list of destinations available + for deployment + items: + description: ApplicationDestination holds information about the + application's destination + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster + and must be set to the Kubernetes control plane API + type: string + type: object + type: array + namespaceResourceBlacklist: + description: NamespaceResourceBlacklist contains list of blacklisted + namespace level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + namespaceResourceWhitelist: + description: NamespaceResourceWhitelist contains list of whitelisted + namespace level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + orphanedResources: + description: OrphanedResources specifies if controller should monitor + orphaned resources of apps in this project + properties: + ignore: + description: Ignore contains a list of resources that are to be + excluded from orphaned resources monitoring + items: + description: OrphanedResourceKey is a reference to a resource + to be ignored from + properties: + group: + type: string + kind: + type: string + name: + type: string + type: object + type: array + warn: + description: Warn indicates if warning condition should be created + for apps which have orphaned resources + type: boolean + type: object + permitOnlyProjectScopedClusters: + description: PermitOnlyProjectScopedClusters determines whether destinations + can only reference clusters which are project-scoped + type: boolean + roles: + description: Roles are user defined RBAC roles associated with this + project + items: + description: ProjectRole represents a role that has access to a + project + properties: + description: + description: Description is a description of the role + type: string + groups: + description: Groups are a list of OIDC group claims bound to + this role + items: + type: string + type: array + jwtTokens: + description: JWTTokens are a list of generated JWT tokens bound + to this role + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + name: + description: Name is a name for this role + type: string + policies: + description: Policies Stores a list of casbin formatted strings + that define access policies for the role in the project + items: + type: string + type: array + required: + - name + type: object + type: array + signatureKeys: + description: SignatureKeys contains a list of PGP key IDs that commits + in Git must be signed with in order to be allowed for sync + items: + description: SignatureKey is the specification of a key required + to verify commit signatures with + properties: + keyID: + description: The ID of the key in hexadecimal notation + type: string + required: + - keyID + type: object + type: array + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sourceRepos: + description: SourceRepos contains list of repository URLs which can + be used for deployment + items: + type: string + type: array + syncWindows: + description: SyncWindows controls when syncs can be run for apps in + this project + items: + description: SyncWindow contains the kind, time, duration and attributes + that are used to assign the syncWindows to apps + properties: + applications: + description: Applications contains a list of applications that + the window will apply to + items: + type: string + type: array + clusters: + description: Clusters contains a list of clusters that the window + will apply to + items: + type: string + type: array + duration: + description: Duration is the amount of time the sync window + will be open + type: string + kind: + description: Kind defines if the window allows or blocks syncs + type: string + manualSync: + description: ManualSync enables manual syncs when they would + otherwise be blocked + type: boolean + namespaces: + description: Namespaces contains a list of namespaces that the + window will apply to + items: + type: string + type: array + schedule: + description: Schedule is the time the window will begin, specified + in cron format + type: string + timeZone: + description: TimeZone of the sync that will be applied to the + schedule + type: string + type: object + type: array + type: object + status: + description: AppProjectStatus contains status information for AppProject + CRs + properties: + jwtTokensByRole: + additionalProperties: + description: JWTTokens represents a list of JWT tokens + properties: + items: + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + type: object + description: JWTTokensByRole contains a list of JWT tokens issued + for a given role + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml new file mode 100644 index 000000000..8a8b0b0f1 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml @@ -0,0 +1,258 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + name: argocdexports.argoproj.io +spec: + group: argoproj.io + names: + kind: ArgoCDExport + listKind: ArgoCDExportList + plural: argocdexports + singular: argocdexport + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCDExport is the Schema for the argocdexports API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDExportSpec defines the desired state of ArgoCDExport + properties: + argocd: + description: Argocd is the name of the ArgoCD instance to export. + type: string + image: + description: Image is the container image to use for the export Job. + type: string + schedule: + description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + type: string + storage: + description: Storage defines the storage configuration options. + properties: + backend: + description: Backend defines the storage backend to use, must + be "local" (the default), "aws", "azure" or "gcp". + type: string + pvc: + description: PVC is the desired characteristics for a PersistentVolumeClaim. + properties: + accessModes: + description: 'AccessModes contains the desired access modes + the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify either: * + An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified data + source, it will create a new volume based on the contents + of the specified data source. If the AnyVolumeDataSource + feature gate is enabled, this field will always have the + same contents as the DataSourceRef field.' + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'Specifies the object from which to populate + the volume with data, if a non-empty volume is desired. + This may be any local object from a non-empty API group + (non core object) or a PersistentVolumeClaim object. When + this field is specified, volume binding will only succeed + if the type of the specified object matches some installed + volume populator or dynamic provisioner. This field will + replace the functionality of the DataSource field and as + such if both fields are non-empty, they must have the same + value. For backwards compatibility, both fields (DataSource + and DataSourceRef) will be set to the same value automatically + if one of them is empty and the other is non-empty. There + are two important differences between DataSource and DataSourceRef: + * While DataSource only allows two specific types of objects, + DataSourceRef allows any non-core object, as well as PersistentVolumeClaim + objects. * While DataSource ignores disallowed values (dropping + them), DataSourceRef preserves all values, and generates + an error if a disallowed value is specified. (Alpha) Using + this field requires the AnyVolumeDataSource feature gate + to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum resources the + volume should have. If RecoverVolumeExpansionFailure feature + is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher + than capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: A label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required + by the claim. Value of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: VolumeName is the binding reference to the PersistentVolume + backing this claim. + type: string + type: object + secretName: + description: SecretName is the name of a Secret with encryption + key, credentials, etc. + type: string + type: object + version: + description: Version is the tag/digest to use for the export Job container + image. + type: string + required: + - argocd + type: object + status: + description: ArgoCDExportStatus defines the observed state of ArgoCDExport + properties: + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCDExport + is in its lifecycle. There are five possible phase values: Pending: + The ArgoCDExport has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: + All of the containers for the ArgoCDExport are still running, or + in the process of starting or restarting. Succeeded: All containers + for the ArgoCDExport have terminated in success, and will not be + restarted. Failed: At least one container has terminated in failure, + either exited with non-zero status or was terminated by the system. + Unknown: For some reason the state of the ArgoCDExport could not + be obtained.' + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml new file mode 100644 index 000000000..87d7c51d6 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -0,0 +1,6373 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + name: argocds.argoproj.io +spec: + group: argoproj.io + names: + kind: ArgoCD + listKind: ArgoCDList + plural: argocds + singular: argocd + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCD is the Schema for the argocds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDSpec defines the desired state of ArgoCD + properties: + applicationInstanceLabelKey: + description: ApplicationInstanceLabelKey is the key name where Argo + CD injects the app name as a tracking label. + type: string + applicationSet: + description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet + controller should be installed. + properties: + env: + description: Env lets you specify environment for applicationSet + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: ExtraCommandArgs allows users to pass command line + arguments to ApplicationSet controller. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the Argo CD ApplicationSet image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for ApplicationSet. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD ApplicationSet image tag. + (optional) + type: string + webhookServer: + description: WebhookServerSpec defines the options for the ApplicationSet + Webhook Server component. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + use for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the + Route resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the + contents of the ca certificate of the final destination. When + using reencrypt termination this file should be + provided in order to have routers use it for health + checks on the secure connection. If this field is + not specified, the router may provide its own destination + CA and perform hostname validation using the short + service name (service.namespace.svc), which allows + infrastructure generated certificates to automatically + verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to + a route. While each router may make its own decisions + on which ports to expose, this is normally port + 80. \n * Allow - traffic is sent to the server on + the insecure port (default) * Disable - no traffic + is allowed on the insecure port. * Redirect - clients + are redirected to the secure port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + type: object + type: object + banner: + description: Banner defines an additional banner to be displayed in + Argo CD UI + properties: + content: + description: Content defines the banner message content to display + type: string + url: + description: URL defines an optional URL to be used as banner + message link + type: string + required: + - content + type: object + configManagementPlugins: + description: ConfigManagementPlugins is used to specify additional + config management plugins. + type: string + controller: + description: Controller defines the Application Controller options + for ArgoCD. + properties: + appSync: + description: "AppSync is used to control the sync frequency, by + default the ArgoCD controller polls Git every 3m. \n Set this + to a duration, e.g. 10m or 600s to control the synchronisation + frequency." + type: string + env: + description: Env lets you specify environment for application + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + logFormat: + description: LogFormat refers to the log format used by the Application + Controller component. Defaults to ArgoCDDefaultLogFormat if + not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level used by the Application + Controller component. Defaults to ArgoCDDefaultLogLevel if not + configured. Valid options are debug, info, error, and warn. + type: string + parallelismLimit: + description: ParallelismLimit defines the limit for parallel kubectl + operations + format: int32 + type: integer + processors: + description: Processors contains the options for the Application + Controller processors. + properties: + operation: + description: Operation is the number of application operation + processors. + format: int32 + type: integer + status: + description: Status is the number of application status processors. + format: int32 + type: integer + type: object + resources: + description: Resources defines the Compute Resources required + by the container for the Application Controller. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + sharding: + description: Sharding contains the options for the Application + Controller sharding configuration. + properties: + clustersPerShard: + description: ClustersPerShard defines the maximum number of + clusters managed by each argocd shard + format: int32 + minimum: 1 + type: integer + dynamicScalingEnabled: + description: DynamicScalingEnabled defines whether dynamic + scaling should be enabled for Application Controller component + type: boolean + enabled: + description: Enabled defines whether sharding should be enabled + on the Application Controller component. + type: boolean + maxShards: + description: MaxShards defines the maximum number of shards + at any given point + format: int32 + type: integer + minShards: + description: MinShards defines the minimum number of shards + at any given point + format: int32 + minimum: 1 + type: integer + replicas: + description: Replicas defines the number of replicas to run + in the Application controller shard. + format: int32 + type: integer + type: object + type: object + disableAdmin: + description: DisableAdmin will disable the admin user. + type: boolean + extraConfig: + additionalProperties: + type: string + description: "ExtraConfig can be used to add fields to Argo CD configmap + that are not supported by Argo CD CRD. \n Note: ExtraConfig takes + precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` + = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. + In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] + = true." + type: object + gaAnonymizeUsers: + description: GAAnonymizeUsers toggles user IDs being hashed before + sending to google analytics. + type: boolean + gaTrackingID: + description: GATrackingID is the google analytics tracking ID to use. + type: string + grafana: + description: Grafana defines the Grafana server options for ArgoCD. + properties: + enabled: + description: Enabled will toggle Grafana support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + image: + description: Image is the Grafana container image. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + resources: + description: Resources defines the Compute Resources required + by the container for Grafana. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Grafana Deployment. + format: int32 + type: integer + version: + description: Version is the Grafana container image tag. + type: string + required: + - enabled + type: object + ha: + description: HA options for High Availability support for the Redis + component. + properties: + enabled: + description: Enabled will toggle HA support globally for Argo + CD. + type: boolean + redisProxyImage: + description: RedisProxyImage is the Redis HAProxy container image. + type: string + redisProxyVersion: + description: RedisProxyVersion is the Redis HAProxy container + image tag. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for HA. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - enabled + type: object + helpChatText: + description: HelpChatText is the text for getting chat help, defaults + to "Chat now!" + type: string + helpChatURL: + description: HelpChatURL is the URL for getting chat help, this will + typically be your Slack channel for support. + type: string + image: + description: Image is the ArgoCD container image for all ArgoCD components. + type: string + import: + description: Import is the import/restore options for ArgoCD. + properties: + name: + description: Name of an ArgoCDExport from which to import data. + type: string + namespace: + description: Namespace for the ArgoCDExport, defaults to the same + namespace as the ArgoCD. + type: string + required: + - name + type: object + initialRepositories: + description: InitialRepositories to configure Argo CD with upon creation + of the cluster. + type: string + initialSSHKnownHosts: + description: InitialSSHKnownHosts defines the SSH known hosts data + upon creation of the cluster for connecting Git repositories via + SSH. + properties: + excludedefaulthosts: + description: ExcludeDefaultHosts describes whether you would like + to include the default list of SSH Known Hosts provided by ArgoCD. + type: boolean + keys: + description: Keys describes a custom set of SSH Known Hosts that + you would like to have included in your ArgoCD server. + type: string + type: object + kustomizeBuildOptions: + description: KustomizeBuildOptions is used to specify build options/parameters + to use with `kustomize build`. + type: string + kustomizeVersions: + description: KustomizeVersions is a listing of configured versions + of Kustomize to be made available within ArgoCD. + items: + description: KustomizeVersionSpec is used to specify information + about a kustomize version to be used within ArgoCD. + properties: + path: + description: Path is the path to a configured kustomize version + on the filesystem of your repo server. + type: string + version: + description: Version is a configured kustomize version in the + format of vX.Y.Z + type: string + type: object + type: array + monitoring: + description: Monitoring defines whether workload status monitoring + configuration for this instance. + properties: + enabled: + description: Enabled defines whether workload status monitoring + is enabled for this instance or not + type: boolean + required: + - enabled + type: object + nodePlacement: + description: NodePlacement defines NodeSelectors and Taints for Argo + CD workloads + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a field of PodSpec, it is a map of + key value pairs used for node selection + type: object + tolerations: + description: Tolerations allow the pods to schedule onto nodes + with matching taints + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + notifications: + description: Notifications defines whether the Argo CD Notifications + controller should be installed. + properties: + enabled: + description: Enabled defines whether argocd-notifications controller + should be deployed or not + type: boolean + env: + description: Env let you specify environment variables for Notifications + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Image is the Argo CD Notifications image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas to run for + notifications-controller + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Argo CD Notifications. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD Notifications image tag. (optional) + type: string + required: + - enabled + type: object + oidcConfig: + description: OIDCConfig is the OIDC configuration as an alternative + to dex. + type: string + prometheus: + description: Prometheus defines the Prometheus server options for + ArgoCD. + properties: + enabled: + description: Enabled will toggle Prometheus support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Prometheus StatefulSet. + format: int32 + type: integer + required: + - enabled + type: object + rbac: + description: RBAC defines the RBAC configuration for Argo CD. + properties: + defaultPolicy: + description: DefaultPolicy is the name of the default role which + Argo CD will falls back to, when authorizing API requests (optional). + If omitted or empty, users may be still be able to login, but + will see no apps, projects, etc... + type: string + policy: + description: 'Policy is CSV containing user-defined RBAC policies + and role definitions. Policy rules are in the form: p, subject, + resource, action, object, effect Role definitions and bindings + are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + type: string + policyMatcherMode: + description: PolicyMatcherMode configures the matchers function + mode for casbin. There are two options for this, 'glob' for + glob matcher or 'regex' for regex matcher. + type: string + scopes: + description: 'Scopes controls which OIDC scopes to examine during + rbac enforcement (in addition to `sub` scope). If omitted, defaults + to: ''[groups]''.' + type: string + type: object + redis: + description: Redis defines the Redis server options for ArgoCD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the redis server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + disableTLSVerification: + description: DisableTLSVerification defines whether redis server + API should be accessed using strict TLS validation + type: boolean + image: + description: Image is the Redis container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Redis container image tag. + type: string + type: object + repo: + description: Repo defines the repo server options for Argo CD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the repo server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + env: + description: Env lets you specify environment for repo server + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + execTimeout: + description: ExecTimeout specifies the timeout in seconds for + tool execution + type: integer + extraRepoCommandArgs: + description: Extra Command arguments allows users to pass command + line arguments to repo server workload. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraRepoCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the ArgoCD Repo Server container image. + type: string + initContainers: + description: InitContainers defines the list of initialization + containers for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + logFormat: + description: LogFormat describes the log format that should be + used by the Repo Server. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not + set. Valid options are debug, info, error, and warn. + type: string + mountsatoken: + description: MountSAToken describes whether you would like to + have the Repo server mount the service account token + type: boolean + replicas: + description: Replicas defines the number of replicas for argocd-repo-server. + Value should be greater than or equal to 0. Default is nil. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceaccount: + description: ServiceAccount defines the ServiceAccount user that + you would like the Repo server to use + type: string + sidecarContainers: + description: SidecarContainers defines the list of sidecar containers + for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + verifytls: + description: VerifyTLS defines whether repo server API should + be accessed using strict TLS validation + type: boolean + version: + description: Version is the ArgoCD Repo Server container image + tag. + type: string + volumeMounts: + description: VolumeMounts adds volumeMounts to the repo server + container + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes adds volumes to the repo server deployment + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force and set the ReadOnly + property in VolumeMounts to "true". If omitted, the + default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent disk resource + in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, Read Only, Read + Write.' + type: string + diskName: + description: The Name of the data disk in the blob storage + type: string + diskURI: + description: The URI the data disk in the blob storage + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + kind: + description: 'Expected values Shared: multiple blob + disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that contains Azure + Storage Account Name and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'Required: Monitors is a collection of + Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the mounted root, rather + than the full Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile is the path to key + ring for User, default is /etc/ceph/user.secret More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef is reference to the + authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'Optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to a secret object containing + parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the ConfigMap, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its keys + must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: Driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: Filesystem type to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: Specifies a read-only configuration for + the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage medium should back + this directory. The default is "" which means to use + the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'Total amount of local storage required + for this EmptyDir volume. The size limit is also applicable + for memory medium. The maximum usage on memory medium + EmptyDir would be the minimum value between the SizeLimit + specified here and the sum of memory limits of all + containers in a pod. The default is nil which means + that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "Ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'AccessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify + either: * An existing VolumeSnapshot object + (snapshot.storage.k8s.io/VolumeSnapshot) * + An existing PVC (PersistentVolumeClaim) If + the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. If the AnyVolumeDataSource + feature gate is enabled, this field will always + have the same contents as the DataSourceRef + field.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'Specifies the object from which + to populate the volume with data, if a non-empty + volume is desired. This may be any local object + from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this + field is specified, volume binding will only + succeed if the type of the specified object + matches some installed volume populator or + dynamic provisioner. This field will replace + the functionality of the DataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, both fields (DataSource and + DataSourceRef) will be set to the same value + automatically if one of them is empty and + the other is non-empty. There are two important + differences between DataSource and DataSourceRef: + * While DataSource only allows two specific + types of objects, DataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While DataSource ignores disallowed + values (dropping them), DataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. (Alpha) Using this field + requires the AnyVolumeDataSource feature gate + to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: A label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required + by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: VolumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: FC represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: Driver is the name of the driver to use + for this volume. + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". The default filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command options if any.' + type: object + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef is reference to the + secret object containing sensitive information to + pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the + plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored as metadata + -> name on the dataset for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD resource in GCE. + Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. Must not contain + or start with '..'. If '.' is supplied, the volume + directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator Name. If initiatorName + is specified with iscsiInterface simultaneously, new + iSCSI interface : will + be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iSCSI Interface Name that uses an iSCSI + transport. Defaults to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. The portal is + either an IP or ip_addr:port if the port is other + than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI target and initiator + authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. The Portal is either + an IP or ip_addr:port if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + pdID: + description: ID that identifies Photon Controller persistent + disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: FSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources secrets, configmaps, + and downward API + properties: + defaultMode: + description: Mode bits used to set permissions on created + files by default. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. Directories within the + path are not affected by this setting. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: information about the configMap data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + downwardAPI: + description: information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about the secret data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + type: object + serviceAccountToken: + description: information about the serviceAccountToken + data to project + properties: + audience: + description: Audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: Path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: Quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: Group to map volume access to Default is + no group + type: string + readOnly: + description: ReadOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: Tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: Volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph monitors. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. Default is rbd. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'The rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: The host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO Protection Domain + for the configured storage. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: Indicates whether the storage for a volume + should be ThickProvisioned or ThinProvisioned. Default + is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool associated with + the protection domain. + type: string + system: + description: The name of the storage system as configured + in ScaleIO. + type: string + volumeName: + description: The name of a volume already created in + the ScaleIO system that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start + with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret or its keys + must be defined + type: boolean + secretName: + description: 'Name of the secret in the pod''s namespace + to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + storagePolicyID: + description: Storage Policy Based Management (SPBM) + profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based Management (SPBM) + profile name. + type: string + volumePath: + description: Path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + repositoryCredentials: + description: RepositoryCredentials are the Git pull credentials to + configure Argo CD with upon creation of the cluster. + type: string + resourceActions: + description: ResourceActions customizes resource action behavior. + items: + description: Resource Customization for custom action + properties: + action: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceCustomizations: + description: 'ResourceCustomizations customizes resource behavior. + Keys are in the form: group/Kind. Please note that this is being + deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' + type: string + resourceExclusions: + description: ResourceExclusions is used to completely ignore entire + classes of resource group/kinds. + type: string + resourceHealthChecks: + description: ResourceHealthChecks customizes resource health check + behavior. + items: + description: Resource Customization for custom health check + properties: + check: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceIgnoreDifferences: + description: ResourceIgnoreDifferences customizes resource ignore + difference behavior. + properties: + all: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + resourceIdentifiers: + items: + description: Resource Customization fields for ignore difference + properties: + customization: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + group: + type: string + kind: + type: string + type: object + type: array + type: object + resourceInclusions: + description: ResourceInclusions is used to only include specific group/kinds + in the reconciliation process. + type: string + resourceTrackingMethod: + description: ResourceTrackingMethod defines how Argo CD should track + resources that it manages + type: string + server: + description: Server defines the options for the ArgoCD Server component. + properties: + autoscale: + description: Autoscale defines the autoscale options for the Argo + CD Server component. + properties: + enabled: + description: Enabled will toggle autoscaling support for the + Argo CD Server component. + type: boolean + hpa: + description: HPA defines the HorizontalPodAutoscaler options + for the Argo CD Server component. + properties: + maxReplicas: + description: upper limit for the number of pods that can + be set by the autoscaler; cannot be smaller than MinReplicas. + format: int32 + type: integer + minReplicas: + description: minReplicas is the lower limit for the number + of replicas to which the autoscaler can scale down. It + defaults to 1 pod. minReplicas is allowed to be 0 if + the alpha feature gate HPAScaleToZero is enabled and + at least one Object or External metric is configured. Scaling + is active as long as at least one metric value is available. + format: int32 + type: integer + scaleTargetRef: + description: reference to scaled resource; horizontal + pod autoscaler will learn the current resource consumption + and will set the desired number of pods by using its + Scale subresource. + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + type: string + name: + description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + required: + - kind + - name + type: object + targetCPUUtilizationPercentage: + description: target average CPU utilization (represented + as a percentage of requested CPU) over all the pods; + if not specified the default autoscaling policy will + be used. + format: int32 + type: integer + required: + - maxReplicas + - scaleTargetRef + type: object + required: + - enabled + type: object + env: + description: Env lets you specify environment for API server pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: Extra Command arguments that would append to the + Argo CD server command. ExtraCommandArgs will not be added, + if one of these commands is already part of the server command + with same or different value. + items: + type: string + type: array + grpc: + description: GRPC defines the state for the Argo CD Server GRPC + options. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for the Argo + CD Server GRPC Ingress. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + type: object + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + insecure: + description: Insecure toggles the insecure flag. + type: boolean + logFormat: + description: LogFormat refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if + not set. Valid options are debug, info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas for argocd-server. + Default is nil. Value should be greater than or equal to 0. + Value will be ignored if Autoscaler is enabled. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for the Argo CD server component. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + service: + description: Service defines the options for the Service backing + the ArgoCD Server component. + properties: + type: + description: Type is the ServiceType to use for the Service + resource. + type: string + required: + - type + type: object + type: object + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sso: + description: SSO defines the Single Sign-on configuration for Argo + CD + properties: + dex: + description: Dex contains the configuration for Argo CD dex authentication + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must + be a member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + keycloak: + description: Keycloak contains the configuration for Argo CD keycloak + authentication + properties: + image: + description: Image is the Keycloak container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Keycloak. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + rootCA: + description: Custom root CA certificate for communicating + with the Keycloak OIDC provider + type: string + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the Keycloak container image tag. + type: string + type: object + provider: + description: Provider installs and configures the given SSO Provider + with Argo CD. + type: string + type: object + statusBadgeEnabled: + description: StatusBadgeEnabled toggles application status badge feature. + type: boolean + tls: + description: TLS defines the TLS options for ArgoCD. + properties: + ca: + description: CA defines the CA options. + properties: + configMapName: + description: ConfigMapName is the name of the ConfigMap containing + the CA Certificate. + type: string + secretName: + description: SecretName is the name of the Secret containing + the CA Certificate and Key. + type: string + type: object + initialCerts: + additionalProperties: + type: string + description: InitialCerts defines custom TLS certificates upon + creation of the cluster for connecting Git repositories via + HTTPS. + type: object + type: object + usersAnonymousEnabled: + description: UsersAnonymousEnabled toggles anonymous user access. + The anonymous users get default role permissions specified argocd-rbac-cm. + type: boolean + version: + description: Version is the tag to use with the ArgoCD container image + for all ArgoCD components. + type: string + type: object + status: + description: ArgoCDStatus defines the observed state of ArgoCD + properties: + applicationController: + description: 'ApplicationController is a simple, high-level summary + of where the Argo CD application controller component is in its + lifecycle. There are four possible ApplicationController values: + Pending: The Argo CD application controller component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD application controller component are in a Ready state. Failed: + At least one of the Argo CD application controller component Pods + had a failure. Unknown: The state of the Argo CD application controller + component could not be obtained.' + type: string + applicationSetController: + description: 'ApplicationSetController is a simple, high-level summary + of where the Argo CD applicationSet controller component is in its + lifecycle. There are four possible ApplicationSetController values: + Pending: The Argo CD applicationSet controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD applicationSet controller component are in a Ready + state. Failed: At least one of the Argo CD applicationSet controller + component Pods had a failure. Unknown: The state of the Argo CD + applicationSet controller component could not be obtained.' + type: string + host: + description: Host is the hostname of the Ingress. + type: string + notificationsController: + description: 'NotificationsController is a simple, high-level summary + of where the Argo CD notifications controller component is in its + lifecycle. There are four possible NotificationsController values: + Pending: The Argo CD notifications controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD notifications controller component are in a Ready + state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD + notifications controller component could not be obtained.' + type: string + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCD + is in its lifecycle. There are four possible phase values: Pending: + The ArgoCD has been accepted by the Kubernetes system, but one or + more of the required resources have not been created. Available: + All of the resources for the ArgoCD are ready. Failed: At least + one resource has experienced a failure. Unknown: The state of the + ArgoCD phase could not be obtained.' + type: string + redis: + description: 'Redis is a simple, high-level summary of where the Argo + CD Redis component is in its lifecycle. There are four possible + redis values: Pending: The Argo CD Redis component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Redis component are in a Ready state. Failed: At least one + of the Argo CD Redis component Pods had a failure. Unknown: The + state of the Argo CD Redis component could not be obtained.' + type: string + redisTLSChecksum: + description: RedisTLSChecksum contains the SHA256 checksum of the + latest known state of tls.crt and tls.key in the argocd-operator-redis-tls + secret. + type: string + repo: + description: 'Repo is a simple, high-level summary of where the Argo + CD Repo component is in its lifecycle. There are four possible repo + values: Pending: The Argo CD Repo component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Repo component are in a Ready state. Failed: At least one + of the Argo CD Repo component Pods had a failure. Unknown: The + state of the Argo CD Repo component could not be obtained.' + type: string + repoTLSChecksum: + description: RepoTLSChecksum contains the SHA256 checksum of the latest + known state of tls.crt and tls.key in the argocd-repo-server-tls + secret. + type: string + server: + description: 'Server is a simple, high-level summary of where the + Argo CD server component is in its lifecycle. There are four possible + server values: Pending: The Argo CD server component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD server component are in a Ready state. Failed: At least + one of the Argo CD server component Pods had a failure. Unknown: + The state of the Argo CD server component could not be obtained.' + type: string + sso: + description: 'SSO is a simple, high-level summary of where the Argo + CD SSO(Dex/Keycloak) component is in its lifecycle. There are four + possible sso values: Pending: The Argo CD SSO component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD SSO component are in a Ready state. Failed: At least + one of the Argo CD SSO component Pods had a failure. Unknown: The + state of the Argo CD SSO component could not be obtained.' + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/olm-catalog/argocd-operator/argocd-operator.package.yaml b/deploy/olm-catalog/argocd-operator/argocd-operator.package.yaml index 0400002c8..956740872 100644 --- a/deploy/olm-catalog/argocd-operator/argocd-operator.package.yaml +++ b/deploy/olm-catalog/argocd-operator/argocd-operator.package.yaml @@ -1,5 +1,5 @@ channels: -- currentCSV: argocd-operator.v0.5.0 +- currentCSV: argocd-operator.v0.7.0 name: alpha defaultChannel: alpha packageName: argocd-operator From b25858dad6e310a190a80a7d4b2f6baa4e38f851 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Mon, 21 Aug 2023 12:22:16 +0530 Subject: [PATCH 07/94] feat: Add conversion webhook for ArgoCD v1alpha1 to v1beta1 migration (#964) * Add ArgoCD v1beta1 & deprecate v1alpha1 - Add new ArgoCD v1beta1 api - Mark ArgoCD v1alpha1 as deprecated & add back the removed sso fields - Use server side validation for "kubectl apply" as client side results into failure due to exceeding annotation size limit. Signed-off-by: Siddhesh Ghadi Add funcs for ArgoCD alpha to beta conversion Signed-off-by: Siddhesh Ghadi Add conversion webhook - Create webhook & setup webhook server on 9443 - Disable operator namespaced install via OLM so that OLM can handle certs for webhook server - For manual install, user needs to explicitly configure cert manager to inject certs and enable webhook server in operator by setting env ENABLE_CONVERSION_WEBHOOK="true" Signed-off-by: Siddhesh Ghadi Resolve local build issues Signed-off-by: Siddhesh Ghadi Tweak webhook configs Signed-off-by: Siddhesh Ghadi Update operator installation docs Signed-off-by: Siddhesh Ghadi Add e2e tests Signed-off-by: Siddhesh Ghadi Minor updates Signed-off-by: Siddhesh Ghadi Fix go-lint ci failure Signed-off-by: Siddhesh Ghadi Update docs Signed-off-by: Siddhesh Ghadi Remove webhook from 0.7.0 bundle Signed-off-by: Siddhesh Ghadi Add spaces in bundle Signed-off-by: Siddhesh Ghadi * update 0.8.0 bundle Signed-off-by: Siddhesh Ghadi --------- Signed-off-by: Siddhesh Ghadi --- Dockerfile | 2 +- Makefile | 11 +- PROJECT | 10 + api/v1alpha1/argocd_conversion.go | 577 ++ api/v1alpha1/argocd_conversion_test.go | 552 ++ api/v1alpha1/argocd_types.go | 18 + api/v1alpha1/zz_generated.deepcopy.go | 15 + api/v1beta1/argocd_conversion.go | 4 + api/v1beta1/argocd_types.go | 1022 +++ api/v1beta1/argocd_types_test.go | 48 + api/v1beta1/argocd_webhook.go | 27 + api/v1beta1/groupversion_info.go | 36 + api/v1beta1/zz_generated.deepcopy.go | 1040 +++ ...d-operator-webhook-service_v1_service.yaml | 14 + ...argocd-operator.clusterserviceversion.yaml | 756 +- bundle/manifests/argoproj.io_argocds.yaml | 6457 ++++++++++++++++- config/certmanager/certificate.yaml | 25 + config/certmanager/kustomization.yaml | 5 + config/certmanager/kustomizeconfig.yaml | 16 + config/crd/bases/argoproj.io_argocds.yaml | 6446 +++++++++++++++- config/crd/kustomization.yaml | 4 +- .../crd/patches/cainjection_in_argocds.yaml | 4 +- config/crd/patches/webhook_in_argocds.yaml | 3 +- config/default/kustomization.yaml | 4 +- config/default/manager_webhook_patch.yaml | 23 + config/default/webhookcainjection_patch.yaml | 15 + ...argocd-operator.clusterserviceversion.yaml | 613 +- config/manifests/kustomization.yaml | 38 +- .../samples/argoproj.io_v1beta1_argocd.yaml | 58 + config/samples/kustomization.yaml | 1 + config/webhook/kustomization.yaml | 6 + config/webhook/kustomizeconfig.yaml | 25 + config/webhook/service.yaml | 13 + controllers/argocd/role_test.go | 4 +- ...d-operator-webhook-service_v1_service.yaml | 14 + ...operator.v0.8.0.clusterserviceversion.yaml | 756 +- .../0.8.0/argoproj.io_argocds.yaml | 6457 ++++++++++++++++- docs/install/manual.md | 70 + docs/install/openshift.md | 39 + main.go | 21 +- .../01-argocd-dex.yaml | 12 + .../01-assert.yaml | 17 + .../02-delete.yaml | 7 + .../02-errors.yaml | 14 + .../01-argocd-keycloak.yaml | 12 + .../01-assert.yaml | 16 + .../02-delete.yaml | 9 + .../02-errors.yaml | 13 + .../01-argocd-dex-keycloak-conflict.yaml | 17 + .../01-assert.yaml | 20 + .../02-delete.yaml | 7 + .../02-errors.yaml | 17 + .../01-argocd-dex.yaml | 14 + .../01-assert.yaml | 25 + .../02-delete.yaml | 7 + .../02-errors.yaml | 34 + tests/olm/README.md | 85 + 57 files changed, 25496 insertions(+), 79 deletions(-) create mode 100644 api/v1alpha1/argocd_conversion.go create mode 100644 api/v1alpha1/argocd_conversion_test.go create mode 100644 api/v1beta1/argocd_conversion.go create mode 100644 api/v1beta1/argocd_types.go create mode 100644 api/v1beta1/argocd_types_test.go create mode 100644 api/v1beta1/argocd_webhook.go create mode 100644 api/v1beta1/groupversion_info.go create mode 100644 api/v1beta1/zz_generated.deepcopy.go create mode 100644 bundle/manifests/argocd-operator-webhook-service_v1_service.yaml create mode 100644 config/certmanager/certificate.yaml create mode 100644 config/certmanager/kustomization.yaml create mode 100644 config/certmanager/kustomizeconfig.yaml create mode 100644 config/default/manager_webhook_patch.yaml create mode 100644 config/default/webhookcainjection_patch.yaml create mode 100644 config/samples/argoproj.io_v1beta1_argocd.yaml create mode 100644 config/webhook/kustomization.yaml create mode 100644 config/webhook/kustomizeconfig.yaml create mode 100644 config/webhook/service.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-webhook-service_v1_service.yaml create mode 100644 tests/olm/1-001_alpha_to_beta_dex_conversion/01-argocd-dex.yaml create mode 100644 tests/olm/1-001_alpha_to_beta_dex_conversion/01-assert.yaml create mode 100644 tests/olm/1-001_alpha_to_beta_dex_conversion/02-delete.yaml create mode 100644 tests/olm/1-001_alpha_to_beta_dex_conversion/02-errors.yaml create mode 100644 tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-argocd-keycloak.yaml create mode 100644 tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-assert.yaml create mode 100644 tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-delete.yaml create mode 100644 tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-errors.yaml create mode 100644 tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-argocd-dex-keycloak-conflict.yaml create mode 100644 tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-assert.yaml create mode 100644 tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-delete.yaml create mode 100644 tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-errors.yaml create mode 100644 tests/olm/1-004_beta_to_alpha_conversion/01-argocd-dex.yaml create mode 100644 tests/olm/1-004_beta_to_alpha_conversion/01-assert.yaml create mode 100644 tests/olm/1-004_beta_to_alpha_conversion/02-delete.yaml create mode 100644 tests/olm/1-004_beta_to_alpha_conversion/02-errors.yaml create mode 100644 tests/olm/README.md diff --git a/Dockerfile b/Dockerfile index d134b43cf..964eecc6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ COPY version/ version/ # Build ARG LD_FLAGS -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="$LD_FLAGS" -a -o manager main.go +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="$LD_FLAGS" -a -o manager main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/Makefile b/Makefile index 5c628bc84..7cb643818 100644 --- a/Makefile +++ b/Makefile @@ -107,14 +107,17 @@ docker-push: ## Push docker image with the manager. ##@ Deployment install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | kubectl apply -f - + ## TODO: Remove sed usage after all v1alpha1 references are updated to v1beta1 in codebase. + ## For local testing, conversion webhook defined in crd makes call to webhook for each v1alpha1 reference + ## causing failures as we don't set up the webhook for local testing. + $(KUSTOMIZE) build config/crd | sed '/conversion:/,/- v1beta1/d' |kubectl apply --server-side=true -f - uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. $(KUSTOMIZE) build config/crd | kubectl delete -f - deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | kubectl apply -f - + $(KUSTOMIZE) build config/default | kubectl apply --server-side=true -f - undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. $(KUSTOMIZE) build config/default | kubectl delete -f - @@ -137,7 +140,7 @@ kustomize: ## Download kustomize locally if necessary. ENVTEST = $(shell pwd)/bin/setup-envtest envtest: ## Download envtest-setup locally if necessary. $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest) - $(ENVTEST) use 1.21 + $(ENVTEST) use 1.26 # go-install-tool will 'go install' any package $2 and install it to $1. PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) @@ -210,7 +213,7 @@ ifeq (,$(shell which opm 2>/dev/null)) set -e ;\ mkdir -p $(dir $(OPM)) ;\ OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$${OS}-$${ARCH}-opm ;\ + curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.20.0/$${OS}-$${ARCH}-opm ;\ chmod +x $(OPM) ;\ } else diff --git a/PROJECT b/PROJECT index ffa072639..69dd85072 100644 --- a/PROJECT +++ b/PROJECT @@ -22,4 +22,14 @@ resources: kind: ArgoCDExport path: github.com/argoproj-labs/argocd-operator/api/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + group: argoproj.io + kind: ArgoCD + path: github.com/argoproj-labs/argocd-operator/api/v1beta1 + version: v1beta1 + webhooks: + conversion: true + webhookVersion: v1 version: "3" diff --git a/api/v1alpha1/argocd_conversion.go b/api/v1alpha1/argocd_conversion.go new file mode 100644 index 000000000..104b3f8b4 --- /dev/null +++ b/api/v1alpha1/argocd_conversion.go @@ -0,0 +1,577 @@ +package v1alpha1 + +import ( + "reflect" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + "github.com/argoproj-labs/argocd-operator/api/v1beta1" +) + +var conversionLogger = ctrl.Log.WithName("conversion-webhook") + +// ConvertTo converts this (v1alpha1) ArgoCD to the Hub version (v1beta1). +func (src *ArgoCD) ConvertTo(dstRaw conversion.Hub) error { + conversionLogger.Info("v1alpha1 to v1beta1 conversion requested.") + dst := dstRaw.(*v1beta1.ArgoCD) + + // ObjectMeta conversion + dst.ObjectMeta = src.ObjectMeta + + // Spec conversion + + // sso field + sso := ConvertAlphaToBetaSSO(src.Spec.SSO) + + // in case of conflict, deprecated fields will have more priority during conversion to beta + // deprecated keycloak configs set in alpha (.spec.sso.image, .spec.sso.version, .spec.sso.verifyTLS, .spec.sso.resources), + // override .spec.sso.keycloak in beta + if src.Spec.SSO != nil && !reflect.DeepEqual(src.Spec.SSO, &ArgoCDSSOSpec{}) { + if src.Spec.SSO.Image != "" || src.Spec.SSO.Version != "" || src.Spec.SSO.VerifyTLS != nil || src.Spec.SSO.Resources != nil { + if sso.Keycloak == nil { + sso.Keycloak = &v1beta1.ArgoCDKeycloakSpec{} + } + sso.Keycloak.Image = src.Spec.SSO.Image + sso.Keycloak.Version = src.Spec.SSO.Version + sso.Keycloak.VerifyTLS = src.Spec.SSO.VerifyTLS + sso.Keycloak.Resources = src.Spec.SSO.Resources + } + } + + // deprecated dex configs set in alpha (.spec.dex), override .spec.sso.dex in beta + if src.Spec.Dex != nil && !reflect.DeepEqual(src.Spec.Dex, &ArgoCDDexSpec{}) && (src.Spec.Dex.Config != "" || src.Spec.Dex.OpenShiftOAuth) { + if sso == nil { + sso = &v1beta1.ArgoCDSSOSpec{} + } + sso.Provider = v1beta1.SSOProviderTypeDex + sso.Dex = (*v1beta1.ArgoCDDexSpec)(src.Spec.Dex) + } + + dst.Spec.SSO = sso + + // rest of the fields + dst.Spec.ApplicationSet = ConvertAlphaToBetaApplicationSet(src.Spec.ApplicationSet) + dst.Spec.ExtraConfig = src.Spec.ExtraConfig + dst.Spec.ApplicationInstanceLabelKey = src.Spec.ApplicationInstanceLabelKey + dst.Spec.ConfigManagementPlugins = src.Spec.ConfigManagementPlugins + dst.Spec.Controller = *ConvertAlphaToBetaController(&src.Spec.Controller) + dst.Spec.DisableAdmin = src.Spec.DisableAdmin + dst.Spec.ExtraConfig = src.Spec.ExtraConfig + dst.Spec.GATrackingID = src.Spec.GATrackingID + dst.Spec.GAAnonymizeUsers = src.Spec.GAAnonymizeUsers + dst.Spec.Grafana = *ConvertAlphaToBetaGrafana(&src.Spec.Grafana) + dst.Spec.HA = *ConvertAlphaToBetaHA(&src.Spec.HA) + dst.Spec.HelpChatURL = src.Spec.HelpChatURL + dst.Spec.HelpChatText = src.Spec.HelpChatText + dst.Spec.Image = src.Spec.Image + dst.Spec.Import = (*v1beta1.ArgoCDImportSpec)(src.Spec.Import) + dst.Spec.InitialRepositories = src.Spec.InitialRepositories + dst.Spec.InitialSSHKnownHosts = v1beta1.SSHHostsSpec(src.Spec.InitialSSHKnownHosts) + dst.Spec.KustomizeBuildOptions = src.Spec.KustomizeBuildOptions + dst.Spec.KustomizeVersions = ConvertAlphaToBetaKustomizeVersions(src.Spec.KustomizeVersions) + dst.Spec.OIDCConfig = src.Spec.OIDCConfig + dst.Spec.Monitoring = v1beta1.ArgoCDMonitoringSpec(src.Spec.Monitoring) + dst.Spec.NodePlacement = (*v1beta1.ArgoCDNodePlacementSpec)(src.Spec.NodePlacement) + dst.Spec.Notifications = v1beta1.ArgoCDNotifications(src.Spec.Notifications) + dst.Spec.Prometheus = *ConvertAlphaToBetaPrometheus(&src.Spec.Prometheus) + dst.Spec.RBAC = v1beta1.ArgoCDRBACSpec(src.Spec.RBAC) + dst.Spec.Redis = v1beta1.ArgoCDRedisSpec(src.Spec.Redis) + dst.Spec.Repo = v1beta1.ArgoCDRepoSpec(src.Spec.Repo) + dst.Spec.RepositoryCredentials = src.Spec.RepositoryCredentials + dst.Spec.ResourceCustomizations = src.Spec.ResourceCustomizations + dst.Spec.ResourceHealthChecks = ConvertAlphaToBetaResourceHealthChecks(src.Spec.ResourceHealthChecks) + dst.Spec.ResourceIgnoreDifferences = ConvertAlphaToBetaResourceIgnoreDifferences(src.Spec.ResourceIgnoreDifferences) + dst.Spec.ResourceActions = ConvertAlphaToBetaResourceActions(src.Spec.ResourceActions) + dst.Spec.ResourceExclusions = src.Spec.ResourceExclusions + dst.Spec.ResourceInclusions = src.Spec.ResourceInclusions + dst.Spec.ResourceTrackingMethod = src.Spec.ResourceTrackingMethod + dst.Spec.Server = *ConvertAlphaToBetaServer(&src.Spec.Server) + dst.Spec.SourceNamespaces = src.Spec.SourceNamespaces + dst.Spec.StatusBadgeEnabled = src.Spec.StatusBadgeEnabled + dst.Spec.TLS = *ConvertAlphaToBetaTLS(&src.Spec.TLS) + dst.Spec.UsersAnonymousEnabled = src.Spec.UsersAnonymousEnabled + dst.Spec.Version = src.Spec.Version + dst.Spec.Banner = (*v1beta1.Banner)(src.Spec.Banner) + + // Status conversion + dst.Status = v1beta1.ArgoCDStatus(src.Status) + + return nil +} + +// ConvertFrom converts from the Hub version (v1beta1) to this (v1alpha1) version. +func (dst *ArgoCD) ConvertFrom(srcRaw conversion.Hub) error { + conversionLogger.Info("v1beta1 to v1alpha1 conversion requested.") + + src := srcRaw.(*v1beta1.ArgoCD) + + // ObjectMeta conversion + dst.ObjectMeta = src.ObjectMeta + + // Spec conversion + + // sso field + // ignoring conversions of sso fields from v1beta1 to deprecated v1alpha1 as + // there is no data loss since the new fields in v1beta1 are also present in v1alpha1 & + // v1alpha1 is not used in business logic & only exists for presentation + sso := ConvertBetaToAlphaSSO(src.Spec.SSO) + dst.Spec.SSO = sso + + // rest of the fields + dst.Spec.ApplicationSet = ConvertBetaToAlphaApplicationSet(src.Spec.ApplicationSet) + dst.Spec.ExtraConfig = src.Spec.ExtraConfig + dst.Spec.ApplicationInstanceLabelKey = src.Spec.ApplicationInstanceLabelKey + dst.Spec.ConfigManagementPlugins = src.Spec.ConfigManagementPlugins + dst.Spec.Controller = *ConvertBetaToAlphaController(&src.Spec.Controller) + dst.Spec.DisableAdmin = src.Spec.DisableAdmin + dst.Spec.ExtraConfig = src.Spec.ExtraConfig + dst.Spec.GATrackingID = src.Spec.GATrackingID + dst.Spec.GAAnonymizeUsers = src.Spec.GAAnonymizeUsers + dst.Spec.Grafana = *ConvertBetaToAlphaGrafana(&src.Spec.Grafana) + dst.Spec.HA = *ConvertBetaToAlphaHA(&src.Spec.HA) + dst.Spec.HelpChatURL = src.Spec.HelpChatURL + dst.Spec.HelpChatText = src.Spec.HelpChatText + dst.Spec.Image = src.Spec.Image + dst.Spec.Import = (*ArgoCDImportSpec)(src.Spec.Import) + dst.Spec.InitialRepositories = src.Spec.InitialRepositories + dst.Spec.InitialSSHKnownHosts = SSHHostsSpec(src.Spec.InitialSSHKnownHosts) + dst.Spec.KustomizeBuildOptions = src.Spec.KustomizeBuildOptions + dst.Spec.KustomizeVersions = ConvertBetaToAlphaKustomizeVersions(src.Spec.KustomizeVersions) + dst.Spec.OIDCConfig = src.Spec.OIDCConfig + dst.Spec.Monitoring = ArgoCDMonitoringSpec(src.Spec.Monitoring) + dst.Spec.NodePlacement = (*ArgoCDNodePlacementSpec)(src.Spec.NodePlacement) + dst.Spec.Notifications = ArgoCDNotifications(src.Spec.Notifications) + dst.Spec.Prometheus = *ConvertBetaToAlphaPrometheus(&src.Spec.Prometheus) + dst.Spec.RBAC = ArgoCDRBACSpec(src.Spec.RBAC) + dst.Spec.Redis = ArgoCDRedisSpec(src.Spec.Redis) + dst.Spec.Repo = ArgoCDRepoSpec(src.Spec.Repo) + dst.Spec.RepositoryCredentials = src.Spec.RepositoryCredentials + dst.Spec.ResourceCustomizations = src.Spec.ResourceCustomizations + dst.Spec.ResourceHealthChecks = ConvertBetaToAlphaResourceHealthChecks(src.Spec.ResourceHealthChecks) + dst.Spec.ResourceIgnoreDifferences = ConvertBetaToAlphaResourceIgnoreDifferences(src.Spec.ResourceIgnoreDifferences) + dst.Spec.ResourceActions = ConvertBetaToAlphaResourceActions(src.Spec.ResourceActions) + dst.Spec.ResourceExclusions = src.Spec.ResourceExclusions + dst.Spec.ResourceInclusions = src.Spec.ResourceInclusions + dst.Spec.ResourceTrackingMethod = src.Spec.ResourceTrackingMethod + dst.Spec.Server = *ConvertBetaToAlphaServer(&src.Spec.Server) + dst.Spec.SourceNamespaces = src.Spec.SourceNamespaces + dst.Spec.StatusBadgeEnabled = src.Spec.StatusBadgeEnabled + dst.Spec.TLS = *ConvertBetaToAlphaTLS(&src.Spec.TLS) + dst.Spec.UsersAnonymousEnabled = src.Spec.UsersAnonymousEnabled + dst.Spec.Version = src.Spec.Version + dst.Spec.Banner = (*Banner)(src.Spec.Banner) + + // Status conversion + dst.Status = ArgoCDStatus(src.Status) + + return nil +} + +// Conversion funcs for v1alpha1 to v1beta1. +func ConvertAlphaToBetaController(src *ArgoCDApplicationControllerSpec) *v1beta1.ArgoCDApplicationControllerSpec { + var dst *v1beta1.ArgoCDApplicationControllerSpec + if src != nil { + dst = &v1beta1.ArgoCDApplicationControllerSpec{ + Processors: v1beta1.ArgoCDApplicationControllerProcessorsSpec(src.Processors), + LogLevel: src.LogLevel, + LogFormat: src.LogFormat, + Resources: src.Resources, + ParallelismLimit: src.ParallelismLimit, + AppSync: src.AppSync, + Sharding: v1beta1.ArgoCDApplicationControllerShardSpec(src.Sharding), + Env: src.Env, + } + } + return dst +} + +func ConvertAlphaToBetaWebhookServer(src *WebhookServerSpec) *v1beta1.WebhookServerSpec { + var dst *v1beta1.WebhookServerSpec + if src != nil { + dst = &v1beta1.WebhookServerSpec{ + Host: src.Host, + Ingress: v1beta1.ArgoCDIngressSpec(src.Ingress), + Route: v1beta1.ArgoCDRouteSpec(src.Route), + } + } + return dst +} + +func ConvertAlphaToBetaApplicationSet(src *ArgoCDApplicationSet) *v1beta1.ArgoCDApplicationSet { + var dst *v1beta1.ArgoCDApplicationSet + if src != nil { + dst = &v1beta1.ArgoCDApplicationSet{ + Env: src.Env, + ExtraCommandArgs: src.ExtraCommandArgs, + Image: src.Image, + Version: src.Version, + Resources: src.Resources, + LogLevel: src.LogLevel, + WebhookServer: *ConvertAlphaToBetaWebhookServer(&src.WebhookServer), + } + } + return dst +} + +func ConvertAlphaToBetaGrafana(src *ArgoCDGrafanaSpec) *v1beta1.ArgoCDGrafanaSpec { + var dst *v1beta1.ArgoCDGrafanaSpec + if src != nil { + dst = &v1beta1.ArgoCDGrafanaSpec{ + Enabled: src.Enabled, + Host: src.Host, + Image: src.Image, + Ingress: v1beta1.ArgoCDIngressSpec(src.Ingress), + } + } + return dst +} + +func ConvertAlphaToBetaPrometheus(src *ArgoCDPrometheusSpec) *v1beta1.ArgoCDPrometheusSpec { + var dst *v1beta1.ArgoCDPrometheusSpec + if src != nil { + dst = &v1beta1.ArgoCDPrometheusSpec{ + Enabled: src.Enabled, + Host: src.Host, + Ingress: v1beta1.ArgoCDIngressSpec(src.Ingress), + Route: v1beta1.ArgoCDRouteSpec(src.Route), + Size: src.Size, + } + } + return dst +} + +func ConvertAlphaToBetaSSO(src *ArgoCDSSOSpec) *v1beta1.ArgoCDSSOSpec { + var dst *v1beta1.ArgoCDSSOSpec + if src != nil { + dst = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderType(src.Provider), + Dex: (*v1beta1.ArgoCDDexSpec)(src.Dex), + Keycloak: (*v1beta1.ArgoCDKeycloakSpec)(src.Keycloak), + } + } + return dst +} + +func ConvertAlphaToBetaHA(src *ArgoCDHASpec) *v1beta1.ArgoCDHASpec { + var dst *v1beta1.ArgoCDHASpec + if src != nil { + dst = &v1beta1.ArgoCDHASpec{ + Enabled: src.Enabled, + RedisProxyImage: src.RedisProxyImage, + RedisProxyVersion: src.RedisProxyVersion, + Resources: src.Resources, + } + } + return dst +} + +func ConvertAlphaToBetaTLS(src *ArgoCDTLSSpec) *v1beta1.ArgoCDTLSSpec { + var dst *v1beta1.ArgoCDTLSSpec + if src != nil { + dst = &v1beta1.ArgoCDTLSSpec{ + CA: v1beta1.ArgoCDCASpec(src.CA), + InitialCerts: src.InitialCerts, + } + } + return dst +} + +func ConvertAlphaToBetaServer(src *ArgoCDServerSpec) *v1beta1.ArgoCDServerSpec { + var dst *v1beta1.ArgoCDServerSpec + if src != nil { + dst = &v1beta1.ArgoCDServerSpec{ + Autoscale: v1beta1.ArgoCDServerAutoscaleSpec(src.Autoscale), + GRPC: *ConvertAlphaToBetaGRPC(&src.GRPC), + Host: src.Host, + Ingress: v1beta1.ArgoCDIngressSpec(src.Ingress), + Insecure: src.Insecure, + LogLevel: src.LogLevel, + LogFormat: src.LogFormat, + Replicas: src.Replicas, + Resources: src.Resources, + Route: v1beta1.ArgoCDRouteSpec(src.Route), + Service: v1beta1.ArgoCDServerServiceSpec(src.Service), + Env: src.Env, + ExtraCommandArgs: src.ExtraCommandArgs, + } + } + return dst +} + +func ConvertAlphaToBetaGRPC(src *ArgoCDServerGRPCSpec) *v1beta1.ArgoCDServerGRPCSpec { + var dst *v1beta1.ArgoCDServerGRPCSpec + if src != nil { + dst = &v1beta1.ArgoCDServerGRPCSpec{ + Host: src.Host, + Ingress: v1beta1.ArgoCDIngressSpec(src.Ingress), + } + } + return dst +} + +func ConvertAlphaToBetaKustomizeVersions(src []KustomizeVersionSpec) []v1beta1.KustomizeVersionSpec { + var dst []v1beta1.KustomizeVersionSpec + for _, s := range src { + dst = append(dst, v1beta1.KustomizeVersionSpec{ + Version: s.Version, + Path: s.Path, + }, + ) + } + return dst +} + +func ConvertAlphaToBetaResourceIgnoreDifferences(src *ResourceIgnoreDifference) *v1beta1.ResourceIgnoreDifference { + var dst *v1beta1.ResourceIgnoreDifference + if src != nil { + dst = &v1beta1.ResourceIgnoreDifference{ + All: (*v1beta1.IgnoreDifferenceCustomization)(src.All), + ResourceIdentifiers: ConvertAlphaToBetaResourceIdentifiers(src.ResourceIdentifiers), + } + } + return dst +} + +func ConvertAlphaToBetaResourceIdentifiers(src []ResourceIdentifiers) []v1beta1.ResourceIdentifiers { + var dst []v1beta1.ResourceIdentifiers + for _, s := range src { + dst = append(dst, v1beta1.ResourceIdentifiers{ + Group: s.Group, + Kind: s.Kind, + Customization: v1beta1.IgnoreDifferenceCustomization(s.Customization), + }, + ) + } + return dst +} + +func ConvertAlphaToBetaResourceActions(src []ResourceAction) []v1beta1.ResourceAction { + var dst []v1beta1.ResourceAction + for _, s := range src { + dst = append(dst, v1beta1.ResourceAction{ + Group: s.Group, + Kind: s.Kind, + Action: s.Action, + }, + ) + } + return dst +} + +func ConvertAlphaToBetaResourceHealthChecks(src []ResourceHealthCheck) []v1beta1.ResourceHealthCheck { + var dst []v1beta1.ResourceHealthCheck + for _, s := range src { + dst = append(dst, v1beta1.ResourceHealthCheck{ + Group: s.Group, + Kind: s.Kind, + Check: s.Check, + }, + ) + } + return dst +} + +// Conversion funcs for v1beta1 to v1alpha1. +func ConvertBetaToAlphaController(src *v1beta1.ArgoCDApplicationControllerSpec) *ArgoCDApplicationControllerSpec { + var dst *ArgoCDApplicationControllerSpec + if src != nil { + dst = &ArgoCDApplicationControllerSpec{ + Processors: ArgoCDApplicationControllerProcessorsSpec(src.Processors), + LogLevel: src.LogLevel, + LogFormat: src.LogFormat, + Resources: src.Resources, + ParallelismLimit: src.ParallelismLimit, + AppSync: src.AppSync, + Sharding: ArgoCDApplicationControllerShardSpec(src.Sharding), + Env: src.Env, + } + } + return dst +} + +func ConvertBetaToAlphaWebhookServer(src *v1beta1.WebhookServerSpec) *WebhookServerSpec { + var dst *WebhookServerSpec + if src != nil { + dst = &WebhookServerSpec{ + Host: src.Host, + Ingress: ArgoCDIngressSpec(src.Ingress), + Route: ArgoCDRouteSpec(src.Route), + } + } + return dst +} + +func ConvertBetaToAlphaApplicationSet(src *v1beta1.ArgoCDApplicationSet) *ArgoCDApplicationSet { + var dst *ArgoCDApplicationSet + if src != nil { + dst = &ArgoCDApplicationSet{ + Env: src.Env, + ExtraCommandArgs: src.ExtraCommandArgs, + Image: src.Image, + Version: src.Version, + Resources: src.Resources, + LogLevel: src.LogLevel, + WebhookServer: *ConvertBetaToAlphaWebhookServer(&src.WebhookServer), + } + } + return dst +} + +func ConvertBetaToAlphaGrafana(src *v1beta1.ArgoCDGrafanaSpec) *ArgoCDGrafanaSpec { + var dst *ArgoCDGrafanaSpec + if src != nil { + dst = &ArgoCDGrafanaSpec{ + Enabled: src.Enabled, + Host: src.Host, + Image: src.Image, + Ingress: ArgoCDIngressSpec(src.Ingress), + } + } + return dst +} + +func ConvertBetaToAlphaPrometheus(src *v1beta1.ArgoCDPrometheusSpec) *ArgoCDPrometheusSpec { + var dst *ArgoCDPrometheusSpec + if src != nil { + dst = &ArgoCDPrometheusSpec{ + Enabled: src.Enabled, + Host: src.Host, + Ingress: ArgoCDIngressSpec(src.Ingress), + Route: ArgoCDRouteSpec(src.Route), + Size: src.Size, + } + } + return dst +} + +func ConvertBetaToAlphaSSO(src *v1beta1.ArgoCDSSOSpec) *ArgoCDSSOSpec { + var dst *ArgoCDSSOSpec + if src != nil { + dst = &ArgoCDSSOSpec{ + Provider: SSOProviderType(src.Provider), + Dex: (*ArgoCDDexSpec)(src.Dex), + Keycloak: (*ArgoCDKeycloakSpec)(src.Keycloak), + } + } + return dst +} + +func ConvertBetaToAlphaHA(src *v1beta1.ArgoCDHASpec) *ArgoCDHASpec { + var dst *ArgoCDHASpec + if src != nil { + dst = &ArgoCDHASpec{ + Enabled: src.Enabled, + RedisProxyImage: src.RedisProxyImage, + RedisProxyVersion: src.RedisProxyVersion, + Resources: src.Resources, + } + } + return dst +} + +func ConvertBetaToAlphaTLS(src *v1beta1.ArgoCDTLSSpec) *ArgoCDTLSSpec { + var dst *ArgoCDTLSSpec + if src != nil { + dst = &ArgoCDTLSSpec{ + CA: ArgoCDCASpec(src.CA), + InitialCerts: src.InitialCerts, + } + } + return dst +} + +func ConvertBetaToAlphaServer(src *v1beta1.ArgoCDServerSpec) *ArgoCDServerSpec { + var dst *ArgoCDServerSpec + if src != nil { + dst = &ArgoCDServerSpec{ + Autoscale: ArgoCDServerAutoscaleSpec(src.Autoscale), + GRPC: *ConvertBetaToAlphaGRPC(&src.GRPC), + Host: src.Host, + Ingress: ArgoCDIngressSpec(src.Ingress), + Insecure: src.Insecure, + LogLevel: src.LogLevel, + LogFormat: src.LogFormat, + Replicas: src.Replicas, + Resources: src.Resources, + Route: ArgoCDRouteSpec(src.Route), + Service: ArgoCDServerServiceSpec(src.Service), + Env: src.Env, + ExtraCommandArgs: src.ExtraCommandArgs, + } + } + return dst +} + +func ConvertBetaToAlphaGRPC(src *v1beta1.ArgoCDServerGRPCSpec) *ArgoCDServerGRPCSpec { + var dst *ArgoCDServerGRPCSpec + if src != nil { + dst = &ArgoCDServerGRPCSpec{ + Host: src.Host, + Ingress: ArgoCDIngressSpec(src.Ingress), + } + } + return dst +} + +func ConvertBetaToAlphaKustomizeVersions(src []v1beta1.KustomizeVersionSpec) []KustomizeVersionSpec { + var dst []KustomizeVersionSpec + for _, s := range src { + dst = append(dst, KustomizeVersionSpec{ + Version: s.Version, + Path: s.Path, + }, + ) + } + return dst +} + +func ConvertBetaToAlphaResourceIgnoreDifferences(src *v1beta1.ResourceIgnoreDifference) *ResourceIgnoreDifference { + var dst *ResourceIgnoreDifference + if src != nil { + dst = &ResourceIgnoreDifference{ + All: (*IgnoreDifferenceCustomization)(src.All), + ResourceIdentifiers: ConvertBetaToAlphaResourceIdentifiers(src.ResourceIdentifiers), + } + } + return dst +} + +func ConvertBetaToAlphaResourceIdentifiers(src []v1beta1.ResourceIdentifiers) []ResourceIdentifiers { + var dst []ResourceIdentifiers + for _, s := range src { + dst = append(dst, ResourceIdentifiers{ + Group: s.Group, + Kind: s.Kind, + Customization: IgnoreDifferenceCustomization(s.Customization), + }, + ) + } + return dst +} + +func ConvertBetaToAlphaResourceActions(src []v1beta1.ResourceAction) []ResourceAction { + var dst []ResourceAction + for _, s := range src { + dst = append(dst, ResourceAction{ + Group: s.Group, + Kind: s.Kind, + Action: s.Action, + }, + ) + } + return dst +} + +func ConvertBetaToAlphaResourceHealthChecks(src []v1beta1.ResourceHealthCheck) []ResourceHealthCheck { + var dst []ResourceHealthCheck + for _, s := range src { + dst = append(dst, ResourceHealthCheck{ + Group: s.Group, + Kind: s.Kind, + Check: s.Check, + }, + ) + } + return dst +} diff --git a/api/v1alpha1/argocd_conversion_test.go b/api/v1alpha1/argocd_conversion_test.go new file mode 100644 index 000000000..08f13d999 --- /dev/null +++ b/api/v1alpha1/argocd_conversion_test.go @@ -0,0 +1,552 @@ +package v1alpha1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/networking/v1" + resourcev1 "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + v1beta1 "github.com/argoproj-labs/argocd-operator/api/v1beta1" +) + +type argoCDAlphaOpt func(*ArgoCD) + +func makeTestArgoCDAlpha(opts ...argoCDAlphaOpt) *ArgoCD { + a := &ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-argocd", + Namespace: "default", + Labels: map[string]string{ + "example": "conversion", + }, + }, + } + for _, o := range opts { + o(a) + } + return a +} + +type argoCDBetaOpt func(*v1beta1.ArgoCD) + +func makeTestArgoCDBeta(opts ...argoCDBetaOpt) *v1beta1.ArgoCD { + a := &v1beta1.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-argocd", + Namespace: "default", + Labels: map[string]string{ + "example": "conversion", + }, + }, + } + for _, o := range opts { + o(a) + } + return a +} + +// in case of conflict, deprecated fields will have more priority during conversion to beta +func TestAlphaToBetaConversion(t *testing.T) { + tests := []struct { + name string + input *ArgoCD + expectedOutput *v1beta1.ArgoCD + }{ + // dex conversion + { + name: ".dex -> .sso.dex", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Dex = &ArgoCDDexSpec{ + OpenShiftOAuth: true, + Image: "test", + Version: "latest", + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: "dex", + Dex: &v1beta1.ArgoCDDexSpec{ + OpenShiftOAuth: true, + Image: "test", + Version: "latest", + }, + } + }), + }, + { + name: "Conflict: .dex & .sso.dex -> .sso.dex (values from v1alpha1.spec.dex)", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Dex = &ArgoCDDexSpec{ + OpenShiftOAuth: true, + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: resourcev1.MustParse("2048Mi"), + corev1.ResourceCPU: resourcev1.MustParse("2000m"), + }, + }, + } + cr.Spec.SSO = &ArgoCDSSOSpec{ + Provider: SSOProviderTypeDex, + Dex: &ArgoCDDexSpec{ + Config: "test-config", + Image: "test-image", + }, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderTypeDex, + Dex: &v1beta1.ArgoCDDexSpec{ + OpenShiftOAuth: true, + Resources: &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceMemory: resourcev1.MustParse("2048Mi"), + corev1.ResourceCPU: resourcev1.MustParse("2000m"), + }, + }, + }, + } + }), + }, + { + name: "Missing dex provider: .dex & .sso.dex -> .spec.sso(values from v1alpha1.spec.dex with dex provider set)", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Dex = &ArgoCDDexSpec{ + Config: "test-config", + } + cr.Spec.SSO = &ArgoCDSSOSpec{ + Dex: &ArgoCDDexSpec{ + OpenShiftOAuth: false, + }, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderTypeDex, + Dex: &v1beta1.ArgoCDDexSpec{ + Config: "test-config", + }, + } + }), + }, + { + name: "Missing dex provider without deprecated dex: .sso.dex -> .sso(values from v1alpha1.spec.sso)", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.SSO = &ArgoCDSSOSpec{ + Dex: &ArgoCDDexSpec{ + OpenShiftOAuth: false, + }, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Dex: &v1beta1.ArgoCDDexSpec{ + OpenShiftOAuth: false, + }, + } + }), + }, + + // dex + keycloak - .spec.dex has more priority + { + name: "Conflict: .dex & .sso.keycloak provider -> .sso.dex + .sso.keycloak with dex provider", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Dex = &ArgoCDDexSpec{ + OpenShiftOAuth: true, + } + cr.Spec.SSO = &ArgoCDSSOSpec{ + Provider: SSOProviderTypeKeycloak, + Keycloak: &ArgoCDKeycloakSpec{ + Image: "keycloak", + }, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderTypeDex, + Dex: &v1beta1.ArgoCDDexSpec{ + OpenShiftOAuth: true, + }, + Keycloak: &v1beta1.ArgoCDKeycloakSpec{ + Image: "keycloak", + }, + } + }), + }, + + // keycloak conversion + { + name: ".sso.VerifyTLS -> .sso.Keycloak.VerifyTLS", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + tls := new(bool) + *tls = false + cr.Spec.SSO = &ArgoCDSSOSpec{ + Provider: SSOProviderTypeKeycloak, + Keycloak: &ArgoCDKeycloakSpec{ + RootCA: "__CA__", + }, + VerifyTLS: tls, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + tls := new(bool) + *tls = false + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderTypeKeycloak, + Keycloak: &v1beta1.ArgoCDKeycloakSpec{ + RootCA: "__CA__", + VerifyTLS: tls, + }, + } + }), + }, + { + name: ".sso.Image without provider -> .sso.Keycloak.Image without provider", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.SSO = &ArgoCDSSOSpec{ + Image: "test-image", + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Keycloak: &v1beta1.ArgoCDKeycloakSpec{ + Image: "test-image", + }, + } + }), + }, + + // other fields + { + name: "ArgoCD Example - Empty", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) {}), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) {}), + }, + { + name: "ArgoCD Example - Dex + RBAC", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Dex = &ArgoCDDexSpec{ + OpenShiftOAuth: true, + } + + defaultPolicy := "role:readonly" + policy := "g, system:cluster-admins, role:admin" + scope := "[groups]" + cr.Spec.RBAC = ArgoCDRBACSpec{ + DefaultPolicy: &defaultPolicy, + Policy: &policy, + Scopes: &scope, + } + + cr.Spec.Server = ArgoCDServerSpec{ + Route: ArgoCDRouteSpec{ + Enabled: true, + }, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderTypeDex, + Dex: &v1beta1.ArgoCDDexSpec{ + OpenShiftOAuth: true, + }, + } + + defaultPolicy := "role:readonly" + policy := "g, system:cluster-admins, role:admin" + scope := "[groups]" + cr.Spec.RBAC = v1beta1.ArgoCDRBACSpec{ + DefaultPolicy: &defaultPolicy, + Policy: &policy, + Scopes: &scope, + } + + cr.Spec.Server = v1beta1.ArgoCDServerSpec{ + Route: v1beta1.ArgoCDRouteSpec{ + Enabled: true, + }, + } + }), + }, + { + name: "ArgoCD Example - ResourceCustomizations", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.ResourceIgnoreDifferences = &ResourceIgnoreDifference{ + All: &IgnoreDifferenceCustomization{ + JsonPointers: []string{ + "/spec/replicas", + }, + ManagedFieldsManagers: []string{ + "kube-controller-manager", + }, + }, + ResourceIdentifiers: []ResourceIdentifiers{ + { + Group: "admissionregistration.k8s.io", + Kind: "MutatingWebhookConfiguration", + Customization: IgnoreDifferenceCustomization{ + JqPathExpressions: []string{ + "'.webhooks[]?.clientConfig.caBundle'", + }, + }, + }, + { + Group: "apps", + Kind: "Deployment", + Customization: IgnoreDifferenceCustomization{ + ManagedFieldsManagers: []string{ + "kube-controller-manager", + }, + JsonPointers: []string{ + "/spec/replicas", + }, + }, + }, + }, + } + cr.Spec.ResourceHealthChecks = []ResourceHealthCheck{ + { + Group: "certmanager.k8s.io", + Kind: "Certificate", + }, + } + cr.Spec.ResourceActions = []ResourceAction{ + { + Group: "apps", + Kind: "Deployment", + }, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.ResourceIgnoreDifferences = &v1beta1.ResourceIgnoreDifference{ + All: &v1beta1.IgnoreDifferenceCustomization{ + JsonPointers: []string{ + "/spec/replicas", + }, + ManagedFieldsManagers: []string{ + "kube-controller-manager", + }, + }, + ResourceIdentifiers: []v1beta1.ResourceIdentifiers{ + { + Group: "admissionregistration.k8s.io", + Kind: "MutatingWebhookConfiguration", + Customization: v1beta1.IgnoreDifferenceCustomization{ + JqPathExpressions: []string{ + "'.webhooks[]?.clientConfig.caBundle'", + }, + }, + }, + { + Group: "apps", + Kind: "Deployment", + Customization: v1beta1.IgnoreDifferenceCustomization{ + ManagedFieldsManagers: []string{ + "kube-controller-manager", + }, + JsonPointers: []string{ + "/spec/replicas", + }, + }, + }, + }, + } + cr.Spec.ResourceHealthChecks = []v1beta1.ResourceHealthCheck{ + { + Group: "certmanager.k8s.io", + Kind: "Certificate", + }, + } + cr.Spec.ResourceActions = []v1beta1.ResourceAction{ + { + Group: "apps", + Kind: "Deployment", + }, + } + }), + }, + { + name: "ArgoCD Example - Image + ExtraConfig", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Image = "test-image" + cr.Spec.ExtraConfig = map[string]string{ + "ping": "pong", + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.Image = "test-image" + cr.Spec.ExtraConfig = map[string]string{ + "ping": "pong", + } + }), + }, + { + name: "ArgoCD Example - Sever + Import", + input: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Server.Autoscale = ArgoCDServerAutoscaleSpec{ + Enabled: true, + } + cr.Spec.Import = &ArgoCDImportSpec{ + Name: "test-name", + } + cr.Spec.Server = ArgoCDServerSpec{ + Host: "test-host.argocd.org", + GRPC: ArgoCDServerGRPCSpec{ + Ingress: ArgoCDIngressSpec{ + Enabled: false, + }, + }, + Ingress: ArgoCDIngressSpec{ + Enabled: true, + TLS: []v1.IngressTLS{ + {Hosts: []string{ + "test-tls", + }}, + }, + }, + Insecure: true, + } + }), + expectedOutput: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.Server.Autoscale = v1beta1.ArgoCDServerAutoscaleSpec{ + Enabled: true, + } + cr.Spec.Import = &v1beta1.ArgoCDImportSpec{ + Name: "test-name", + } + cr.Spec.Server = v1beta1.ArgoCDServerSpec{ + Host: "test-host.argocd.org", + GRPC: v1beta1.ArgoCDServerGRPCSpec{ + Ingress: v1beta1.ArgoCDIngressSpec{ + Enabled: false, + }, + }, + Ingress: v1beta1.ArgoCDIngressSpec{ + Enabled: true, + TLS: []v1.IngressTLS{ + {Hosts: []string{ + "test-tls", + }}, + }, + }, + Insecure: true, + } + }), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + + // Set v1beta1 object in Hub, converted values will be set in this object. + var hub conversion.Hub = &v1beta1.ArgoCD{} + + // Call ConvertTo function to convert v1alpha1 version to v1beta1 + test.input.ConvertTo(hub) + + // Fetch the converted object + result := hub.(*v1beta1.ArgoCD) + + // Compare converted object with expected. + assert.Equal(t, test.expectedOutput, result) + }) + } +} + +// During beta to alpha conversion, converting sso fields back to deprecated fields is ignored as +// there is no data loss since the new fields in v1beta1 are also present in v1alpha1 +func TestBetaToAlphaConversion(t *testing.T) { + tests := []struct { + name string + input *v1beta1.ArgoCD + expectedOutput *ArgoCD + }{ + { + name: "ArgoCD Example - Empty", + input: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) {}), + expectedOutput: makeTestArgoCDAlpha(func(cr *ArgoCD) {}), + }, + { + name: "ArgoCD Example - Image + ExtraConfig", + input: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.Image = "test-image" + cr.Spec.ExtraConfig = map[string]string{ + "ping": "pong", + } + }), + expectedOutput: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.Image = "test-image" + cr.Spec.ExtraConfig = map[string]string{ + "ping": "pong", + } + }), + }, + { + name: "ArgoCD Example - Dex + RBAC", + input: makeTestArgoCDBeta(func(cr *v1beta1.ArgoCD) { + cr.Spec.SSO = &v1beta1.ArgoCDSSOSpec{ + Provider: v1beta1.SSOProviderTypeDex, + Dex: &v1beta1.ArgoCDDexSpec{ + OpenShiftOAuth: true, + }, + } + + defaultPolicy := "role:readonly" + policy := "g, system:cluster-admins, role:admin" + scope := "[groups]" + cr.Spec.RBAC = v1beta1.ArgoCDRBACSpec{ + DefaultPolicy: &defaultPolicy, + Policy: &policy, + Scopes: &scope, + } + + cr.Spec.Server = v1beta1.ArgoCDServerSpec{ + Route: v1beta1.ArgoCDRouteSpec{ + Enabled: true, + }, + } + }), + expectedOutput: makeTestArgoCDAlpha(func(cr *ArgoCD) { + cr.Spec.SSO = &ArgoCDSSOSpec{ + Provider: SSOProviderTypeDex, + Dex: &ArgoCDDexSpec{ + OpenShiftOAuth: true, + }, + } + + defaultPolicy := "role:readonly" + policy := "g, system:cluster-admins, role:admin" + scope := "[groups]" + cr.Spec.RBAC = ArgoCDRBACSpec{ + DefaultPolicy: &defaultPolicy, + Policy: &policy, + Scopes: &scope, + } + + cr.Spec.Server = ArgoCDServerSpec{ + Route: ArgoCDRouteSpec{ + Enabled: true, + }, + } + }), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + + // Add input v1beta1 object in Hub + var hub conversion.Hub = test.input + + result := &ArgoCD{} + // Call ConvertFrom function to convert v1beta1 version to v1alpha + result.ConvertFrom(hub) + + // Compare converted object with expected. + assert.Equal(t, test.expectedOutput, result) + }) + } +} diff --git a/api/v1alpha1/argocd_types.go b/api/v1alpha1/argocd_types.go index 99d79141a..730290784 100644 --- a/api/v1alpha1/argocd_types.go +++ b/api/v1alpha1/argocd_types.go @@ -36,6 +36,7 @@ func init() { // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // Important: Run "make" to regenerate code after modifying this file +// +kubebuilder:deprecatedversion:warning="ArgoCD v1alpha1 is deprecated, please use v1beta1 instead." //+kubebuilder:object:root=true // ArgoCD is the Schema for the argocds API @@ -620,6 +621,19 @@ type ArgoCDSSOSpec struct { // Keycloak contains the configuration for Argo CD keycloak authentication Keycloak *ArgoCDKeycloakSpec `json:"keycloak,omitempty"` + + // Deprecated field. Support dropped in v1beta1 version. + // Image is the SSO container image. + Image string `json:"image,omitempty"` + // Deprecated field. Support dropped in v1beta1 version. + // Resources defines the Compute Resources required by the container for SSO. + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + // Deprecated field. Support dropped in v1beta1 version. + // VerifyTLS set to false disables strict TLS validation. + VerifyTLS *bool `json:"verifyTLS,omitempty"` + // Deprecated field. Support dropped in v1beta1 version. + // Version is the SSO container image tag. + Version string `json:"version,omitempty"` } // KustomizeVersionSpec is used to specify information about a kustomize version to be used within ArgoCD. @@ -802,6 +816,10 @@ type ArgoCDSpec struct { // Banner defines an additional banner to be displayed in Argo CD UI Banner *Banner `json:"banner,omitempty"` + + // Deprecated field. Support dropped in v1beta1 version. + // Dex defines the Dex server options for ArgoCD. + Dex *ArgoCDDexSpec `json:"dex,omitempty"` } // ArgoCDStatus defines the observed state of ArgoCD diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 449473d4c..cbd6307b8 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -766,6 +766,16 @@ func (in *ArgoCDSSOSpec) DeepCopyInto(out *ArgoCDSSOSpec) { *out = new(ArgoCDKeycloakSpec) (*in).DeepCopyInto(*out) } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.VerifyTLS != nil { + in, out := &in.VerifyTLS, &out.VerifyTLS + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDSSOSpec. @@ -943,6 +953,11 @@ func (in *ArgoCDSpec) DeepCopyInto(out *ArgoCDSpec) { *out = new(Banner) **out = **in } + if in.Dex != nil { + in, out := &in.Dex, &out.Dex + *out = new(ArgoCDDexSpec) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDSpec. diff --git a/api/v1beta1/argocd_conversion.go b/api/v1beta1/argocd_conversion.go new file mode 100644 index 000000000..fba05b6da --- /dev/null +++ b/api/v1beta1/argocd_conversion.go @@ -0,0 +1,4 @@ +package v1beta1 + +// Hub marks this type as a conversion hub. +func (*ArgoCD) Hub() {} diff --git a/api/v1beta1/argocd_types.go b/api/v1beta1/argocd_types.go new file mode 100644 index 000000000..560ceca32 --- /dev/null +++ b/api/v1beta1/argocd_types.go @@ -0,0 +1,1022 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "strings" + + routev1 "github.com/openshift/api/route/v1" + + "github.com/argoproj-labs/argocd-operator/common" + + autoscaling "k8s.io/api/autoscaling/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func init() { + SchemeBuilder.Register(&ArgoCD{}, &ArgoCDList{}) +} + +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. +// Important: Run "make" to regenerate code after modifying this file + +// +kubebuilder:storageversion +// +kubebuilder:object:root=true + +// ArgoCD is the Schema for the argocds API +// +k8s:openapi-gen=true +// +kubebuilder:subresource:status +// +operator-sdk:csv:customresourcedefinitions:resources={{ArgoCD,v1beta1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{ArgoCDExport,v1alpha1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{ConfigMap,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{CronJob,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Deployment,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Ingress,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Job,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{PersistentVolumeClaim,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Pod,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Prometheus,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{ReplicaSet,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Route,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Secret,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{Service,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{ServiceMonitor,v1,""}} +// +operator-sdk:csv:customresourcedefinitions:resources={{StatefulSet,v1,""}} +type ArgoCD struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ArgoCDSpec `json:"spec,omitempty"` + Status ArgoCDStatus `json:"status,omitempty"` +} + +// ArgoCDApplicationControllerProcessorsSpec defines the options for the ArgoCD Application Controller processors. +type ArgoCDApplicationControllerProcessorsSpec struct { + // Operation is the number of application operation processors. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Operation Processor Count'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller","urn:alm:descriptor:com.tectonic.ui:number"} + Operation int32 `json:"operation,omitempty"` + + // Status is the number of application status processors. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Status Processor Count'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller","urn:alm:descriptor:com.tectonic.ui:number"} + Status int32 `json:"status,omitempty"` +} + +// ArgoCDApplicationControllerSpec defines the options for the ArgoCD Application Controller component. +type ArgoCDApplicationControllerSpec struct { + // Processors contains the options for the Application Controller processors. + Processors ArgoCDApplicationControllerProcessorsSpec `json:"processors,omitempty"` + + // LogLevel refers to the log level used by the Application Controller component. Defaults to ArgoCDDefaultLogLevel if not configured. Valid options are debug, info, error, and warn. + LogLevel string `json:"logLevel,omitempty"` + + // LogFormat refers to the log format used by the Application Controller component. Defaults to ArgoCDDefaultLogFormat if not configured. Valid options are text or json. + LogFormat string `json:"logFormat,omitempty"` + + // Resources defines the Compute Resources required by the container for the Application Controller. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Requirements'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller","urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // ParallelismLimit defines the limit for parallel kubectl operations + ParallelismLimit int32 `json:"parallelismLimit,omitempty"` + + // AppSync is used to control the sync frequency, by default the ArgoCD + // controller polls Git every 3m. + // + // Set this to a duration, e.g. 10m or 600s to control the synchronisation + // frequency. + // +optional + AppSync *metav1.Duration `json:"appSync,omitempty"` + + // Sharding contains the options for the Application Controller sharding configuration. + Sharding ArgoCDApplicationControllerShardSpec `json:"sharding,omitempty"` + + // Env lets you specify environment for application controller pods + Env []corev1.EnvVar `json:"env,omitempty"` +} + +// ArgoCDApplicationControllerShardSpec defines the options available for enabling sharding for the Application Controller component. +type ArgoCDApplicationControllerShardSpec struct { + + // Enabled defines whether sharding should be enabled on the Application Controller component. + Enabled bool `json:"enabled,omitempty"` + + // Replicas defines the number of replicas to run in the Application controller shard. + Replicas int32 `json:"replicas,omitempty"` + + // DynamicScalingEnabled defines whether dynamic scaling should be enabled for Application Controller component + DynamicScalingEnabled *bool `json:"dynamicScalingEnabled,omitempty"` + + // MinShards defines the minimum number of shards at any given point + // +kubebuilder:validation:Minimum=1 + MinShards int32 `json:"minShards,omitempty"` + + // MaxShards defines the maximum number of shards at any given point + MaxShards int32 `json:"maxShards,omitempty"` + + // ClustersPerShard defines the maximum number of clusters managed by each argocd shard + // +kubebuilder:validation:Minimum=1 + ClustersPerShard int32 `json:"clustersPerShard,omitempty"` +} + +// ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed. +type ArgoCDApplicationSet struct { + + // Env lets you specify environment for applicationSet controller pods + Env []corev1.EnvVar `json:"env,omitempty"` + + // ExtraCommandArgs allows users to pass command line arguments to ApplicationSet controller. + // They get added to default command line arguments provided by the operator. + // Please note that the command line arguments provided as part of ExtraCommandArgs + // will not overwrite the default command line arguments. + ExtraCommandArgs []string `json:"extraCommandArgs,omitempty"` + + // Image is the Argo CD ApplicationSet image (optional) + Image string `json:"image,omitempty"` + + // Version is the Argo CD ApplicationSet image tag. (optional) + Version string `json:"version,omitempty"` + + // Resources defines the Compute Resources required by the container for ApplicationSet. + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // LogLevel describes the log level that should be used by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel if not set. Valid options are debug,info, error, and warn. + LogLevel string `json:"logLevel,omitempty"` + + WebhookServer WebhookServerSpec `json:"webhookServer,omitempty"` +} + +// ArgoCDCASpec defines the CA options for ArgCD. +type ArgoCDCASpec struct { + // ConfigMapName is the name of the ConfigMap containing the CA Certificate. + ConfigMapName string `json:"configMapName,omitempty"` + + // SecretName is the name of the Secret containing the CA Certificate and Key. + SecretName string `json:"secretName,omitempty"` +} + +// ArgoCDCertificateSpec defines the options for the ArgoCD certificates. +type ArgoCDCertificateSpec struct { + // SecretName is the name of the Secret containing the Certificate and Key. + SecretName string `json:"secretName"` +} + +// ArgoCDDexSpec defines the desired state for the Dex server component. +type ArgoCDDexSpec struct { + //Config is the dex connector configuration. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Configuration",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex","urn:alm:descriptor:com.tectonic.ui:text"} + Config string `json:"config,omitempty"` + + // Optional list of required groups a user must be a member of + Groups []string `json:"groups,omitempty"` + + // Image is the Dex container image. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Image",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex","urn:alm:descriptor:com.tectonic.ui:text"} + Image string `json:"image,omitempty"` + + // OpenShiftOAuth enables OpenShift OAuth authentication for the Dex server. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="OpenShift OAuth Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + OpenShiftOAuth bool `json:"openShiftOAuth,omitempty"` + + // Resources defines the Compute Resources required by the container for Dex. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Requirements'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex","urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Version is the Dex container image tag. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex","urn:alm:descriptor:com.tectonic.ui:text"} + Version string `json:"version,omitempty"` +} + +// ArgoCDGrafanaSpec defines the desired state for the Grafana component. +type ArgoCDGrafanaSpec struct { + // Enabled will toggle Grafana support globally for ArgoCD. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Enabled",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + + // Host is the hostname to use for Ingress/Route resources. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Host",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:text"} + Host string `json:"host,omitempty"` + + // Image is the Grafana container image. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Image",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:text"} + Image string `json:"image,omitempty"` + + // Ingress defines the desired state for an Ingress for the Grafana component. + Ingress ArgoCDIngressSpec `json:"ingress,omitempty"` + + // Resources defines the Compute Resources required by the container for Grafana. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Requirements'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Route defines the desired state for an OpenShift Route for the Grafana component. + Route ArgoCDRouteSpec `json:"route,omitempty"` + + // Size is the replica count for the Grafana Deployment. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Size",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:podCount"} + Size *int32 `json:"size,omitempty"` + + // Version is the Grafana container image tag. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:text"} + Version string `json:"version,omitempty"` +} + +// ArgoCDHASpec defines the desired state for High Availability support for Argo CD. +type ArgoCDHASpec struct { + // Enabled will toggle HA support globally for Argo CD. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Enabled",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + + // RedisProxyImage is the Redis HAProxy container image. + RedisProxyImage string `json:"redisProxyImage,omitempty"` + + // RedisProxyVersion is the Redis HAProxy container image tag. + RedisProxyVersion string `json:"redisProxyVersion,omitempty"` + + // Resources defines the Compute Resources required by the container for HA. + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` +} + +// ArgoCDImportSpec defines the desired state for the ArgoCD import/restore process. +type ArgoCDImportSpec struct { + // Name of an ArgoCDExport from which to import data. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Name",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import","urn:alm:descriptor:com.tectonic.ui:text"} + Name string `json:"name"` + + // Namespace for the ArgoCDExport, defaults to the same namespace as the ArgoCD. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Namespace",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import","urn:alm:descriptor:com.tectonic.ui:text"} + Namespace *string `json:"namespace,omitempty"` +} + +// ArgoCDIngressSpec defines the desired state for the Ingress resources. +type ArgoCDIngressSpec struct { + // Annotations is the map of annotations to apply to the Ingress. + Annotations map[string]string `json:"annotations,omitempty"` + + // Enabled will toggle the creation of the Ingress. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Ingress Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus","urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + + // IngressClassName for the Ingress resource. + IngressClassName *string `json:"ingressClassName,omitempty"` + + // Path used for the Ingress resource. + Path string `json:"path,omitempty"` + + // TLS configuration. Currently the Ingress only supports a single TLS + // port, 443. If multiple members of this list specify different hosts, they + // will be multiplexed on the same port according to the hostname specified + // through the SNI TLS extension, if the ingress controller fulfilling the + // ingress supports SNI. + // +optional + TLS []networkingv1.IngressTLS `json:"tls,omitempty"` +} + +// ArgoCDKeycloakSpec defines the desired state for the Keycloak component. +type ArgoCDKeycloakSpec struct { + // Image is the Keycloak container image. + Image string `json:"image,omitempty"` + + // Resources defines the Compute Resources required by the container for Keycloak. + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Custom root CA certificate for communicating with the Keycloak OIDC provider + RootCA string `json:"rootCA,omitempty"` + + // Version is the Keycloak container image tag. + Version string `json:"version,omitempty"` + + // VerifyTLS set to false disables strict TLS validation. + VerifyTLS *bool `json:"verifyTLS,omitempty"` +} + +//+kubebuilder:object:root=true + +// ArgoCDList contains a list of ArgoCD +type ArgoCDList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ArgoCD `json:"items"` +} + +// ArgoCDNotifications defines whether the Argo CD Notifications controller should be installed. +type ArgoCDNotifications struct { + + // Replicas defines the number of replicas to run for notifications-controller + Replicas *int32 `json:"replicas,omitempty"` + + // Enabled defines whether argocd-notifications controller should be deployed or not + Enabled bool `json:"enabled"` + + // Env let you specify environment variables for Notifications pods + Env []corev1.EnvVar `json:"env,omitempty"` + + // Image is the Argo CD Notifications image (optional) + Image string `json:"image,omitempty"` + + // Version is the Argo CD Notifications image tag. (optional) + Version string `json:"version,omitempty"` + + // Resources defines the Compute Resources required by the container for Argo CD Notifications. + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // LogLevel describes the log level that should be used by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel if not set. Valid options are debug,info, error, and warn. + LogLevel string `json:"logLevel,omitempty"` +} + +// ArgoCDPrometheusSpec defines the desired state for the Prometheus component. +type ArgoCDPrometheusSpec struct { + // Enabled will toggle Prometheus support globally for ArgoCD. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Enabled",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + + // Host is the hostname to use for Ingress/Route resources. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Host",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus","urn:alm:descriptor:com.tectonic.ui:text"} + Host string `json:"host,omitempty"` + + // Ingress defines the desired state for an Ingress for the Prometheus component. + Ingress ArgoCDIngressSpec `json:"ingress,omitempty"` + + // Route defines the desired state for an OpenShift Route for the Prometheus component. + Route ArgoCDRouteSpec `json:"route,omitempty"` + + // Size is the replica count for the Prometheus StatefulSet. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Size",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus","urn:alm:descriptor:com.tectonic.ui:podCount"} + Size *int32 `json:"size,omitempty"` +} + +// ArgoCDRBACSpec defines the desired state for the Argo CD RBAC configuration. +type ArgoCDRBACSpec struct { + // DefaultPolicy is the name of the default role which Argo CD will falls back to, when + // authorizing API requests (optional). If omitted or empty, users may be still be able to login, + // but will see no apps, projects, etc... + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Default Policy'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC","urn:alm:descriptor:com.tectonic.ui:text"} + DefaultPolicy *string `json:"defaultPolicy,omitempty"` + + // Policy is CSV containing user-defined RBAC policies and role definitions. + // Policy rules are in the form: + // p, subject, resource, action, object, effect + // Role definitions and bindings are in the form: + // g, subject, inherited-subject + // See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md for additional information. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Policy",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC","urn:alm:descriptor:com.tectonic.ui:text"} + Policy *string `json:"policy,omitempty"` + + // Scopes controls which OIDC scopes to examine during rbac enforcement (in addition to `sub` scope). + // If omitted, defaults to: '[groups]'. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Scopes",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC","urn:alm:descriptor:com.tectonic.ui:text"} + Scopes *string `json:"scopes,omitempty"` + + // PolicyMatcherMode configures the matchers function mode for casbin. + // There are two options for this, 'glob' for glob matcher or 'regex' for regex matcher. + PolicyMatcherMode *string `json:"policyMatcherMode,omitempty"` +} + +// ArgoCDRedisSpec defines the desired state for the Redis server component. +type ArgoCDRedisSpec struct { + // Image is the Redis container image. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Image",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis","urn:alm:descriptor:com.tectonic.ui:text"} + Image string `json:"image,omitempty"` + + // Resources defines the Compute Resources required by the container for Redis. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Requirements'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis","urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Version is the Redis container image tag. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis","urn:alm:descriptor:com.tectonic.ui:text"} + Version string `json:"version,omitempty"` + + // DisableTLSVerification defines whether redis server API should be accessed using strict TLS validation + DisableTLSVerification bool `json:"disableTLSVerification,omitempty"` + + // AutoTLS specifies the method to use for automatic TLS configuration for the redis server + // The value specified here can currently be: + // - openshift - Use the OpenShift service CA to request TLS config + AutoTLS string `json:"autotls,omitempty"` +} + +// ArgoCDRepoSpec defines the desired state for the Argo CD repo server component. +type ArgoCDRepoSpec struct { + + // Extra Command arguments allows users to pass command line arguments to repo server workload. They get added to default command line arguments provided + // by the operator. + // Please note that the command line arguments provided as part of ExtraRepoCommandArgs will not overwrite the default command line arguments. + ExtraRepoCommandArgs []string `json:"extraRepoCommandArgs,omitempty"` + + // LogLevel describes the log level that should be used by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not set. Valid options are debug, info, error, and warn. + LogLevel string `json:"logLevel,omitempty"` + + // LogFormat describes the log format that should be used by the Repo Server. Defaults to ArgoCDDefaultLogFormat if not configured. Valid options are text or json. + LogFormat string `json:"logFormat,omitempty"` + + // MountSAToken describes whether you would like to have the Repo server mount the service account token + MountSAToken bool `json:"mountsatoken,omitempty"` + + // Replicas defines the number of replicas for argocd-repo-server. Value should be greater than or equal to 0. Default is nil. + Replicas *int32 `json:"replicas,omitempty"` + + // Resources defines the Compute Resources required by the container for Redis. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Requirements'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo","urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // ServiceAccount defines the ServiceAccount user that you would like the Repo server to use + ServiceAccount string `json:"serviceaccount,omitempty"` + + // VerifyTLS defines whether repo server API should be accessed using strict TLS validation + VerifyTLS bool `json:"verifytls,omitempty"` + + // AutoTLS specifies the method to use for automatic TLS configuration for the repo server + // The value specified here can currently be: + // - openshift - Use the OpenShift service CA to request TLS config + AutoTLS string `json:"autotls,omitempty"` + + // Image is the ArgoCD Repo Server container image. + Image string `json:"image,omitempty"` + + // Version is the ArgoCD Repo Server container image tag. + Version string `json:"version,omitempty"` + + // ExecTimeout specifies the timeout in seconds for tool execution + ExecTimeout *int `json:"execTimeout,omitempty"` + + // Env lets you specify environment for repo server pods + Env []corev1.EnvVar `json:"env,omitempty"` + + // Volumes adds volumes to the repo server deployment + Volumes []corev1.Volume `json:"volumes,omitempty"` + + // VolumeMounts adds volumeMounts to the repo server container + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` + + // InitContainers defines the list of initialization containers for the repo server deployment + InitContainers []corev1.Container `json:"initContainers,omitempty"` + + // SidecarContainers defines the list of sidecar containers for the repo server deployment + SidecarContainers []corev1.Container `json:"sidecarContainers,omitempty"` +} + +// ArgoCDRouteSpec defines the desired state for an OpenShift Route. +type ArgoCDRouteSpec struct { + // Annotations is the map of annotations to use for the Route resource. + Annotations map[string]string `json:"annotations,omitempty"` + + // Labels is the map of labels to use for the Route resource + Labels map[string]string `json:"labels,omitempty"` + + // Enabled will toggle the creation of the OpenShift Route. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Route Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana","urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus","urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + + // Path the router watches for, to route traffic for to the service. + Path string `json:"path,omitempty"` + + // TLS provides the ability to configure certificates and termination for the Route. + TLS *routev1.TLSConfig `json:"tls,omitempty"` + + // WildcardPolicy if any for the route. Currently only 'Subdomain' or 'None' is allowed. + WildcardPolicy *routev1.WildcardPolicyType `json:"wildcardPolicy,omitempty"` +} + +// ArgoCDServerAutoscaleSpec defines the desired state for autoscaling the Argo CD Server component. +type ArgoCDServerAutoscaleSpec struct { + // Enabled will toggle autoscaling support for the Argo CD Server component. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Autoscale Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + + // HPA defines the HorizontalPodAutoscaler options for the Argo CD Server component. + HPA *autoscaling.HorizontalPodAutoscalerSpec `json:"hpa,omitempty"` +} + +// ArgoCDServerGRPCSpec defines the desired state for the Argo CD Server GRPC options. +type ArgoCDServerGRPCSpec struct { + // Host is the hostname to use for Ingress/Route resources. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="GRPC Host",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:text"} + Host string `json:"host,omitempty"` + + // Ingress defines the desired state for the Argo CD Server GRPC Ingress. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="GRPC Ingress Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Ingress ArgoCDIngressSpec `json:"ingress,omitempty"` +} + +// ArgoCDServerSpec defines the options for the ArgoCD Server component. +type ArgoCDServerSpec struct { + // Autoscale defines the autoscale options for the Argo CD Server component. + Autoscale ArgoCDServerAutoscaleSpec `json:"autoscale,omitempty"` + + // GRPC defines the state for the Argo CD Server GRPC options. + GRPC ArgoCDServerGRPCSpec `json:"grpc,omitempty"` + + // Host is the hostname to use for Ingress/Route resources. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Host",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:text"} + Host string `json:"host,omitempty"` + + // Ingress defines the desired state for an Ingress for the Argo CD Server component. + Ingress ArgoCDIngressSpec `json:"ingress,omitempty"` + + // Insecure toggles the insecure flag. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Insecure",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Insecure bool `json:"insecure,omitempty"` + + // LogLevel refers to the log level to be used by the ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if not set. Valid options are debug, info, error, and warn. + LogLevel string `json:"logLevel,omitempty"` + + // LogFormat refers to the log level to be used by the ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat if not configured. Valid options are text or json. + LogFormat string `json:"logFormat,omitempty"` + + // Replicas defines the number of replicas for argocd-server. Default is nil. Value should be greater than or equal to 0. Value will be ignored if Autoscaler is enabled. + Replicas *int32 `json:"replicas,omitempty"` + + // Resources defines the Compute Resources required by the container for the Argo CD server component. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Requirements'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:resourceRequirements"} + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + + // Route defines the desired state for an OpenShift Route for the Argo CD Server component. + Route ArgoCDRouteSpec `json:"route,omitempty"` + + // Service defines the options for the Service backing the ArgoCD Server component. + Service ArgoCDServerServiceSpec `json:"service,omitempty"` + + // Env lets you specify environment for API server pods + Env []corev1.EnvVar `json:"env,omitempty"` + + // Extra Command arguments that would append to the Argo CD server command. + // ExtraCommandArgs will not be added, if one of these commands is already part of the server command + // with same or different value. + ExtraCommandArgs []string `json:"extraCommandArgs,omitempty"` +} + +// ArgoCDServerServiceSpec defines the Service options for Argo CD Server component. +type ArgoCDServerServiceSpec struct { + // Type is the ServiceType to use for the Service resource. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Service Type'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:text"} + Type corev1.ServiceType `json:"type"` +} + +// Resource Customization for custom health check +type ResourceHealthCheck struct { + Group string `json:"group,omitempty"` + Kind string `json:"kind,omitempty"` + Check string `json:"check,omitempty"` +} + +// Resource Customization for ignore difference +type ResourceIgnoreDifference struct { + All *IgnoreDifferenceCustomization `json:"all,omitempty"` + ResourceIdentifiers []ResourceIdentifiers `json:"resourceIdentifiers,omitempty"` +} + +// Resource Customization fields for ignore difference +type ResourceIdentifiers struct { + Group string `json:"group,omitempty"` + Kind string `json:"kind,omitempty"` + Customization IgnoreDifferenceCustomization `json:"customization,omitempty"` +} + +type IgnoreDifferenceCustomization struct { + JqPathExpressions []string `json:"jqPathExpressions,omitempty"` + JsonPointers []string `json:"jsonPointers,omitempty"` + ManagedFieldsManagers []string `json:"managedFieldsManagers,omitempty"` +} + +// Resource Customization for custom action +type ResourceAction struct { + Group string `json:"group,omitempty"` + Kind string `json:"kind,omitempty"` + Action string `json:"action,omitempty"` +} + +// SSOProviderType string defines the type of SSO provider. +type SSOProviderType string + +const ( + // SSOProviderTypeKeycloak means keycloak will be Installed and Integrated with Argo CD. A new realm with name argocd + // will be created in this keycloak. This realm will have a client with name argocd that uses OpenShift v4 as Identity Provider. + SSOProviderTypeKeycloak SSOProviderType = "keycloak" + + // SSOProviderTypeDex means dex will be Installed and Integrated with Argo CD. + SSOProviderTypeDex SSOProviderType = "dex" +) + +// ArgoCDSSOSpec defines SSO provider. +type ArgoCDSSOSpec struct { + // Provider installs and configures the given SSO Provider with Argo CD. + Provider SSOProviderType `json:"provider,omitempty"` + + // Dex contains the configuration for Argo CD dex authentication + Dex *ArgoCDDexSpec `json:"dex,omitempty"` + + // Keycloak contains the configuration for Argo CD keycloak authentication + Keycloak *ArgoCDKeycloakSpec `json:"keycloak,omitempty"` +} + +// KustomizeVersionSpec is used to specify information about a kustomize version to be used within ArgoCD. +type KustomizeVersionSpec struct { + // Version is a configured kustomize version in the format of vX.Y.Z + Version string `json:"version,omitempty"` + // Path is the path to a configured kustomize version on the filesystem of your repo server. + Path string `json:"path,omitempty"` +} + +// ArgoCDMonitoringSpec is used to configure workload status monitoring for a given Argo CD instance. +// It triggers creation of serviceMonitor and PrometheusRules that alert users when a given workload +// status meets a certain criteria. For e.g, it can fire an alert if the application controller is +// pending for x mins consecutively. +type ArgoCDMonitoringSpec struct { + // Enabled defines whether workload status monitoring is enabled for this instance or not + Enabled bool `json:"enabled"` +} + +// ArgoCDNodePlacementSpec is used to specify NodeSelector and Tolerations for Argo CD workloads +type ArgoCDNodePlacementSpec struct { + // NodeSelector is a field of PodSpec, it is a map of key value pairs used for node selection + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // Tolerations allow the pods to schedule onto nodes with matching taints + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` +} + +// ArgoCDSpec defines the desired state of ArgoCD +// +k8s:openapi-gen=true +type ArgoCDSpec struct { + + // ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed. + ApplicationSet *ArgoCDApplicationSet `json:"applicationSet,omitempty"` + + // ApplicationInstanceLabelKey is the key name where Argo CD injects the app name as a tracking label. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Application Instance Label Key'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ApplicationInstanceLabelKey string `json:"applicationInstanceLabelKey,omitempty"` + + // ConfigManagementPlugins is used to specify additional config management plugins. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Config Management Plugins'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ConfigManagementPlugins string `json:"configManagementPlugins,omitempty"` + + // Controller defines the Application Controller options for ArgoCD. + Controller ArgoCDApplicationControllerSpec `json:"controller,omitempty"` + + // DisableAdmin will disable the admin user. + DisableAdmin bool `json:"disableAdmin,omitempty"` + + // ExtraConfig can be used to add fields to Argo CD configmap that are not supported by Argo CD CRD. + // + // Note: ExtraConfig takes precedence over Argo CD CRD. + // For example, A user sets `argocd.Spec.DisableAdmin` = true and also + // `a.Spec.ExtraConfig["admin.enabled"]` = true. In this case, operator updates + // Argo CD Configmap as follows -> argocd-cm.Data["admin.enabled"] = true. + ExtraConfig map[string]string `json:"extraConfig,omitempty"` + + // GATrackingID is the google analytics tracking ID to use. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Google Analytics Tracking ID'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + GATrackingID string `json:"gaTrackingID,omitempty"` + + // GAAnonymizeUsers toggles user IDs being hashed before sending to google analytics. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Google Analytics Anonymize Users'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch","urn:alm:descriptor:com.tectonic.ui:advanced"} + GAAnonymizeUsers bool `json:"gaAnonymizeUsers,omitempty"` + + // Grafana defines the Grafana server options for ArgoCD. + Grafana ArgoCDGrafanaSpec `json:"grafana,omitempty"` + + // HA options for High Availability support for the Redis component. + HA ArgoCDHASpec `json:"ha,omitempty"` + + // HelpChatURL is the URL for getting chat help, this will typically be your Slack channel for support. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Help Chat URL'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + HelpChatURL string `json:"helpChatURL,omitempty"` + + // HelpChatText is the text for getting chat help, defaults to "Chat now!" + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Help Chat Text'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + HelpChatText string `json:"helpChatText,omitempty"` + + // Image is the ArgoCD container image for all ArgoCD components. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Image",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD","urn:alm:descriptor:com.tectonic.ui:text"} + Image string `json:"image,omitempty"` + + // Import is the import/restore options for ArgoCD. + Import *ArgoCDImportSpec `json:"import,omitempty"` + + // InitialRepositories to configure Argo CD with upon creation of the cluster. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Initial Repositories'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + InitialRepositories string `json:"initialRepositories,omitempty"` + + // InitialSSHKnownHosts defines the SSH known hosts data upon creation of the cluster for connecting Git repositories via SSH. + InitialSSHKnownHosts SSHHostsSpec `json:"initialSSHKnownHosts,omitempty"` + + // KustomizeBuildOptions is used to specify build options/parameters to use with `kustomize build`. + KustomizeBuildOptions string `json:"kustomizeBuildOptions,omitempty"` + + // KustomizeVersions is a listing of configured versions of Kustomize to be made available within ArgoCD. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Kustomize Build Options'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + KustomizeVersions []KustomizeVersionSpec `json:"kustomizeVersions,omitempty"` + + // OIDCConfig is the OIDC configuration as an alternative to dex. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="OIDC Config'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + OIDCConfig string `json:"oidcConfig,omitempty"` + + // Monitoring defines whether workload status monitoring configuration for this instance. + Monitoring ArgoCDMonitoringSpec `json:"monitoring,omitempty"` + + // NodePlacement defines NodeSelectors and Taints for Argo CD workloads + NodePlacement *ArgoCDNodePlacementSpec `json:"nodePlacement,omitempty"` + + // Notifications defines whether the Argo CD Notifications controller should be installed. + Notifications ArgoCDNotifications `json:"notifications,omitempty"` + + // Prometheus defines the Prometheus server options for ArgoCD. + Prometheus ArgoCDPrometheusSpec `json:"prometheus,omitempty"` + + // RBAC defines the RBAC configuration for Argo CD. + RBAC ArgoCDRBACSpec `json:"rbac,omitempty"` + + // Redis defines the Redis server options for ArgoCD. + Redis ArgoCDRedisSpec `json:"redis,omitempty"` + + // Repo defines the repo server options for Argo CD. + Repo ArgoCDRepoSpec `json:"repo,omitempty"` + + // RepositoryCredentials are the Git pull credentials to configure Argo CD with upon creation of the cluster. + RepositoryCredentials string `json:"repositoryCredentials,omitempty"` + + // ResourceCustomizations customizes resource behavior. Keys are in the form: group/Kind. Please note that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ResourceCustomizations string `json:"resourceCustomizations,omitempty"` + + // ResourceHealthChecks customizes resource health check behavior. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Health Check Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ResourceHealthChecks []ResourceHealthCheck `json:"resourceHealthChecks,omitempty"` + + // ResourceIgnoreDifferences customizes resource ignore difference behavior. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Ignore Difference Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ResourceIgnoreDifferences *ResourceIgnoreDifference `json:"resourceIgnoreDifferences,omitempty"` + + // ResourceActions customizes resource action behavior. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Action Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ResourceActions []ResourceAction `json:"resourceActions,omitempty"` + + // ResourceExclusions is used to completely ignore entire classes of resource group/kinds. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Exclusions'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ResourceExclusions string `json:"resourceExclusions,omitempty"` + + // ResourceInclusions is used to only include specific group/kinds in the + // reconciliation process. + ResourceInclusions string `json:"resourceInclusions,omitempty"` + + // ResourceTrackingMethod defines how Argo CD should track resources that it manages + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Tracking Method'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} + ResourceTrackingMethod string `json:"resourceTrackingMethod,omitempty"` + + // Server defines the options for the ArgoCD Server component. + Server ArgoCDServerSpec `json:"server,omitempty"` + + // SourceNamespaces defines the namespaces application resources are allowed to be created in + SourceNamespaces []string `json:"sourceNamespaces,omitempty"` + + // SSO defines the Single Sign-on configuration for Argo CD + SSO *ArgoCDSSOSpec `json:"sso,omitempty"` + + // StatusBadgeEnabled toggles application status badge feature. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Status Badge Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch","urn:alm:descriptor:com.tectonic.ui:advanced"} + StatusBadgeEnabled bool `json:"statusBadgeEnabled,omitempty"` + + // TLS defines the TLS options for ArgoCD. + TLS ArgoCDTLSSpec `json:"tls,omitempty"` + + // UsersAnonymousEnabled toggles anonymous user access. + // The anonymous users get default role permissions specified argocd-rbac-cm. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Anonymous Users Enabled'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch","urn:alm:descriptor:com.tectonic.ui:advanced"} + UsersAnonymousEnabled bool `json:"usersAnonymousEnabled,omitempty"` + + // Version is the tag to use with the ArgoCD container image for all ArgoCD components. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD","urn:alm:descriptor:com.tectonic.ui:text"} + Version string `json:"version,omitempty"` + + // Banner defines an additional banner to be displayed in Argo CD UI + Banner *Banner `json:"banner,omitempty"` +} + +// ArgoCDStatus defines the observed state of ArgoCD +// +k8s:openapi-gen=true +type ArgoCDStatus struct { + // ApplicationController is a simple, high-level summary of where the Argo CD application controller component is in its lifecycle. + // There are four possible ApplicationController values: + // Pending: The Argo CD application controller component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD application controller component are in a Ready state. + // Failed: At least one of the Argo CD application controller component Pods had a failure. + // Unknown: The state of the Argo CD application controller component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="ApplicationController",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + ApplicationController string `json:"applicationController,omitempty"` + + // ApplicationSetController is a simple, high-level summary of where the Argo CD applicationSet controller component is in its lifecycle. + // There are four possible ApplicationSetController values: + // Pending: The Argo CD applicationSet controller component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD applicationSet controller component are in a Ready state. + // Failed: At least one of the Argo CD applicationSet controller component Pods had a failure. + // Unknown: The state of the Argo CD applicationSet controller component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="ApplicationSetController",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + ApplicationSetController string `json:"applicationSetController,omitempty"` + + // SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) component is in its lifecycle. + // There are four possible sso values: + // Pending: The Argo CD SSO component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD SSO component are in a Ready state. + // Failed: At least one of the Argo CD SSO component Pods had a failure. + // Unknown: The state of the Argo CD SSO component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="SSO",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + SSO string `json:"sso,omitempty"` + + // NotificationsController is a simple, high-level summary of where the Argo CD notifications controller component is in its lifecycle. + // There are four possible NotificationsController values: + // Pending: The Argo CD notifications controller component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD notifications controller component are in a Ready state. + // Failed: At least one of the Argo CD notifications controller component Pods had a failure. + // Unknown: The state of the Argo CD notifications controller component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="NotificationsController",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + NotificationsController string `json:"notificationsController,omitempty"` + + // Phase is a simple, high-level summary of where the ArgoCD is in its lifecycle. + // There are four possible phase values: + // Pending: The ArgoCD has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Available: All of the resources for the ArgoCD are ready. + // Failed: At least one resource has experienced a failure. + // Unknown: The state of the ArgoCD phase could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="Phase",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + Phase string `json:"phase,omitempty"` + + // Redis is a simple, high-level summary of where the Argo CD Redis component is in its lifecycle. + // There are four possible redis values: + // Pending: The Argo CD Redis component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD Redis component are in a Ready state. + // Failed: At least one of the Argo CD Redis component Pods had a failure. + // Unknown: The state of the Argo CD Redis component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="Redis",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + Redis string `json:"redis,omitempty"` + + // Repo is a simple, high-level summary of where the Argo CD Repo component is in its lifecycle. + // There are four possible repo values: + // Pending: The Argo CD Repo component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD Repo component are in a Ready state. + // Failed: At least one of the Argo CD Repo component Pods had a failure. + // Unknown: The state of the Argo CD Repo component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="Repo",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + Repo string `json:"repo,omitempty"` + + // Server is a simple, high-level summary of where the Argo CD server component is in its lifecycle. + // There are four possible server values: + // Pending: The Argo CD server component has been accepted by the Kubernetes system, but one or more of the required resources have not been created. + // Running: All of the required Pods for the Argo CD server component are in a Ready state. + // Failed: At least one of the Argo CD server component Pods had a failure. + // Unknown: The state of the Argo CD server component could not be obtained. + //+operator-sdk:csv:customresourcedefinitions:type=status,displayName="Server",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text"} + Server string `json:"server,omitempty"` + + // RepoTLSChecksum contains the SHA256 checksum of the latest known state of tls.crt and tls.key in the argocd-repo-server-tls secret. + RepoTLSChecksum string `json:"repoTLSChecksum,omitempty"` + + // RedisTLSChecksum contains the SHA256 checksum of the latest known state of tls.crt and tls.key in the argocd-operator-redis-tls secret. + RedisTLSChecksum string `json:"redisTLSChecksum,omitempty"` + + // Host is the hostname of the Ingress. + Host string `json:"host,omitempty"` +} + +// Banner defines an additional banner message to be displayed in Argo CD UI +// https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/#banners +type Banner struct { + // Content defines the banner message content to display + Content string `json:"content"` + // URL defines an optional URL to be used as banner message link + URL string `json:"url,omitempty"` +} + +// ArgoCDTLSSpec defines the TLS options for ArgCD. +type ArgoCDTLSSpec struct { + // CA defines the CA options. + CA ArgoCDCASpec `json:"ca,omitempty"` + + // InitialCerts defines custom TLS certificates upon creation of the cluster for connecting Git repositories via HTTPS. + InitialCerts map[string]string `json:"initialCerts,omitempty"` +} + +type SSHHostsSpec struct { + // ExcludeDefaultHosts describes whether you would like to include the default + // list of SSH Known Hosts provided by ArgoCD. + ExcludeDefaultHosts bool `json:"excludedefaulthosts,omitempty"` + + // Keys describes a custom set of SSH Known Hosts that you would like to + // have included in your ArgoCD server. + Keys string `json:"keys,omitempty"` +} + +// WebhookServerSpec defines the options for the ApplicationSet Webhook Server component. +type WebhookServerSpec struct { + + // Host is the hostname to use for Ingress/Route resources. + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Host",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server","urn:alm:descriptor:com.tectonic.ui:text"} + Host string `json:"host,omitempty"` + + // Ingress defines the desired state for an Ingress for the Application set webhook component. + Ingress ArgoCDIngressSpec `json:"ingress,omitempty"` + + // Route defines the desired state for an OpenShift Route for the Application set webhook component. + Route ArgoCDRouteSpec `json:"route,omitempty"` +} + +// IsDeletionFinalizerPresent checks if the instance has deletion finalizer +func (argocd *ArgoCD) IsDeletionFinalizerPresent() bool { + for _, finalizer := range argocd.GetFinalizers() { + if finalizer == common.ArgoCDDeletionFinalizer { + return true + } + } + return false +} + +// WantsAutoTLS returns true if user configured a route with reencryption +// termination policy. +func (s *ArgoCDServerSpec) WantsAutoTLS() bool { + return s.Route.TLS != nil && s.Route.TLS.Termination == routev1.TLSTerminationReencrypt +} + +// WantsAutoTLS returns true if the repository server configuration has set +// the autoTLS toggle to a supported provider. +func (r *ArgoCDRepoSpec) WantsAutoTLS() bool { + return r.AutoTLS == "openshift" +} + +// WantsAutoTLS returns true if the redis server configuration has set +// the autoTLS toggle to a supported provider. +func (r *ArgoCDRedisSpec) WantsAutoTLS() bool { + return r.AutoTLS == "openshift" +} + +// ApplicationInstanceLabelKey returns either the custom application instance +// label key if set, or the default value. +func (a *ArgoCD) ApplicationInstanceLabelKey() string { + if a.Spec.ApplicationInstanceLabelKey != "" { + return a.Spec.ApplicationInstanceLabelKey + } else { + return common.ArgoCDDefaultApplicationInstanceLabelKey + } +} + +// ResourceTrackingMethod represents the Argo CD resource tracking method to use +type ResourceTrackingMethod int + +const ( + ResourceTrackingMethodInvalid ResourceTrackingMethod = -1 + ResourceTrackingMethodLabel ResourceTrackingMethod = 0 + ResourceTrackingMethodAnnotation ResourceTrackingMethod = 1 + ResourceTrackingMethodAnnotationAndLabel ResourceTrackingMethod = 2 +) + +const ( + stringResourceTrackingMethodLabel string = "label" + stringResourceTrackingMethodAnnotation string = "annotation" + stringResourceTrackingMethodAnnotationAndLabel string = "annotation+label" +) + +// String returns the string representation for a ResourceTrackingMethod +func (r ResourceTrackingMethod) String() string { + switch r { + case ResourceTrackingMethodLabel: + return stringResourceTrackingMethodLabel + case ResourceTrackingMethodAnnotation: + return stringResourceTrackingMethodAnnotation + case ResourceTrackingMethodAnnotationAndLabel: + return stringResourceTrackingMethodAnnotationAndLabel + } + + // Default is to use label + return stringResourceTrackingMethodLabel +} + +// ParseResourceTrackingMethod parses a string into a resource tracking method +func ParseResourceTrackingMethod(name string) ResourceTrackingMethod { + switch name { + case stringResourceTrackingMethodLabel, "": + return ResourceTrackingMethodLabel + case stringResourceTrackingMethodAnnotation: + return ResourceTrackingMethodAnnotation + case stringResourceTrackingMethodAnnotationAndLabel: + return ResourceTrackingMethodAnnotationAndLabel + } + + return ResourceTrackingMethodInvalid +} + +// ToLower returns the lower case representation for a SSOProviderType +func (p SSOProviderType) ToLower() SSOProviderType { + str := string(p) + return SSOProviderType(strings.ToLower(str)) +} diff --git a/api/v1beta1/argocd_types_test.go b/api/v1beta1/argocd_types_test.go new file mode 100644 index 000000000..66096bfb7 --- /dev/null +++ b/api/v1beta1/argocd_types_test.go @@ -0,0 +1,48 @@ +package v1beta1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/argoproj-labs/argocd-operator/common" +) + +func Test_ArgoCD_ApplicationInstanceLabelKey(t *testing.T) { + cr := &ArgoCD{} + cr.Spec.ApplicationInstanceLabelKey = "my.corp/instance" + assert.Equal(t, cr.ApplicationInstanceLabelKey(), "my.corp/instance") + cr = &ArgoCD{} + assert.Equal(t, cr.ApplicationInstanceLabelKey(), common.ArgoCDDefaultApplicationInstanceLabelKey) +} + +func Test_ResourceTrackingMethodToString(t *testing.T) { + testdata := []struct { + rtm ResourceTrackingMethod + str string + }{ + {ResourceTrackingMethodLabel, stringResourceTrackingMethodLabel}, + {ResourceTrackingMethodAnnotation, stringResourceTrackingMethodAnnotation}, + {ResourceTrackingMethodAnnotationAndLabel, stringResourceTrackingMethodAnnotationAndLabel}, + {20, stringResourceTrackingMethodLabel}, + } + for _, tt := range testdata { + rtm := tt.rtm + assert.Equal(t, tt.str, rtm.String()) + } +} + +func Test_ParseResourceTrackingMethod(t *testing.T) { + testdata := []struct { + rtm ResourceTrackingMethod + str string + }{ + {ResourceTrackingMethodLabel, stringResourceTrackingMethodLabel}, + {ResourceTrackingMethodAnnotation, stringResourceTrackingMethodAnnotation}, + {ResourceTrackingMethodAnnotationAndLabel, stringResourceTrackingMethodAnnotationAndLabel}, + {ResourceTrackingMethodInvalid, "invalid"}, + } + for _, tt := range testdata { + assert.Equal(t, tt.rtm, ParseResourceTrackingMethod(tt.str)) + } +} diff --git a/api/v1beta1/argocd_webhook.go b/api/v1beta1/argocd_webhook.go new file mode 100644 index 000000000..7f0c5c23a --- /dev/null +++ b/api/v1beta1/argocd_webhook.go @@ -0,0 +1,27 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" +) + +func (r *ArgoCD) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} diff --git a/api/v1beta1/groupversion_info.go b/api/v1beta1/groupversion_info.go new file mode 100644 index 000000000..3b8f2df43 --- /dev/null +++ b/api/v1beta1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 contains API Schema definitions for the argoproj.io v1beta1 API group +// +kubebuilder:object:generate=true +// +groupName=argoproj.io +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "argoproj.io", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000..864d81bca --- /dev/null +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,1040 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta1 + +import ( + routev1 "github.com/openshift/api/route/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" + "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCD) DeepCopyInto(out *ArgoCD) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCD. +func (in *ArgoCD) DeepCopy() *ArgoCD { + if in == nil { + return nil + } + out := new(ArgoCD) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArgoCD) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDApplicationControllerProcessorsSpec) DeepCopyInto(out *ArgoCDApplicationControllerProcessorsSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDApplicationControllerProcessorsSpec. +func (in *ArgoCDApplicationControllerProcessorsSpec) DeepCopy() *ArgoCDApplicationControllerProcessorsSpec { + if in == nil { + return nil + } + out := new(ArgoCDApplicationControllerProcessorsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDApplicationControllerShardSpec) DeepCopyInto(out *ArgoCDApplicationControllerShardSpec) { + *out = *in + if in.DynamicScalingEnabled != nil { + in, out := &in.DynamicScalingEnabled, &out.DynamicScalingEnabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDApplicationControllerShardSpec. +func (in *ArgoCDApplicationControllerShardSpec) DeepCopy() *ArgoCDApplicationControllerShardSpec { + if in == nil { + return nil + } + out := new(ArgoCDApplicationControllerShardSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDApplicationControllerSpec) DeepCopyInto(out *ArgoCDApplicationControllerSpec) { + *out = *in + out.Processors = in.Processors + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.AppSync != nil { + in, out := &in.AppSync, &out.AppSync + *out = new(metav1.Duration) + **out = **in + } + in.Sharding.DeepCopyInto(&out.Sharding) + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDApplicationControllerSpec. +func (in *ArgoCDApplicationControllerSpec) DeepCopy() *ArgoCDApplicationControllerSpec { + if in == nil { + return nil + } + out := new(ArgoCDApplicationControllerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDApplicationSet) DeepCopyInto(out *ArgoCDApplicationSet) { + *out = *in + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ExtraCommandArgs != nil { + in, out := &in.ExtraCommandArgs, &out.ExtraCommandArgs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + in.WebhookServer.DeepCopyInto(&out.WebhookServer) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDApplicationSet. +func (in *ArgoCDApplicationSet) DeepCopy() *ArgoCDApplicationSet { + if in == nil { + return nil + } + out := new(ArgoCDApplicationSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDCASpec) DeepCopyInto(out *ArgoCDCASpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDCASpec. +func (in *ArgoCDCASpec) DeepCopy() *ArgoCDCASpec { + if in == nil { + return nil + } + out := new(ArgoCDCASpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDCertificateSpec) DeepCopyInto(out *ArgoCDCertificateSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDCertificateSpec. +func (in *ArgoCDCertificateSpec) DeepCopy() *ArgoCDCertificateSpec { + if in == nil { + return nil + } + out := new(ArgoCDCertificateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDDexSpec) DeepCopyInto(out *ArgoCDDexSpec) { + *out = *in + if in.Groups != nil { + in, out := &in.Groups, &out.Groups + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDDexSpec. +func (in *ArgoCDDexSpec) DeepCopy() *ArgoCDDexSpec { + if in == nil { + return nil + } + out := new(ArgoCDDexSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDGrafanaSpec) DeepCopyInto(out *ArgoCDGrafanaSpec) { + *out = *in + in.Ingress.DeepCopyInto(&out.Ingress) + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + in.Route.DeepCopyInto(&out.Route) + if in.Size != nil { + in, out := &in.Size, &out.Size + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDGrafanaSpec. +func (in *ArgoCDGrafanaSpec) DeepCopy() *ArgoCDGrafanaSpec { + if in == nil { + return nil + } + out := new(ArgoCDGrafanaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDHASpec) DeepCopyInto(out *ArgoCDHASpec) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDHASpec. +func (in *ArgoCDHASpec) DeepCopy() *ArgoCDHASpec { + if in == nil { + return nil + } + out := new(ArgoCDHASpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDImportSpec) DeepCopyInto(out *ArgoCDImportSpec) { + *out = *in + if in.Namespace != nil { + in, out := &in.Namespace, &out.Namespace + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDImportSpec. +func (in *ArgoCDImportSpec) DeepCopy() *ArgoCDImportSpec { + if in == nil { + return nil + } + out := new(ArgoCDImportSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDIngressSpec) DeepCopyInto(out *ArgoCDIngressSpec) { + *out = *in + 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 + } + } + if in.IngressClassName != nil { + in, out := &in.IngressClassName, &out.IngressClassName + *out = new(string) + **out = **in + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = make([]networkingv1.IngressTLS, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDIngressSpec. +func (in *ArgoCDIngressSpec) DeepCopy() *ArgoCDIngressSpec { + if in == nil { + return nil + } + out := new(ArgoCDIngressSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDKeycloakSpec) DeepCopyInto(out *ArgoCDKeycloakSpec) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.VerifyTLS != nil { + in, out := &in.VerifyTLS, &out.VerifyTLS + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDKeycloakSpec. +func (in *ArgoCDKeycloakSpec) DeepCopy() *ArgoCDKeycloakSpec { + if in == nil { + return nil + } + out := new(ArgoCDKeycloakSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDList) DeepCopyInto(out *ArgoCDList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArgoCD, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDList. +func (in *ArgoCDList) DeepCopy() *ArgoCDList { + if in == nil { + return nil + } + out := new(ArgoCDList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArgoCDList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDMonitoringSpec) DeepCopyInto(out *ArgoCDMonitoringSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDMonitoringSpec. +func (in *ArgoCDMonitoringSpec) DeepCopy() *ArgoCDMonitoringSpec { + if in == nil { + return nil + } + out := new(ArgoCDMonitoringSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDNodePlacementSpec) DeepCopyInto(out *ArgoCDNodePlacementSpec) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDNodePlacementSpec. +func (in *ArgoCDNodePlacementSpec) DeepCopy() *ArgoCDNodePlacementSpec { + if in == nil { + return nil + } + out := new(ArgoCDNodePlacementSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDNotifications) DeepCopyInto(out *ArgoCDNotifications) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDNotifications. +func (in *ArgoCDNotifications) DeepCopy() *ArgoCDNotifications { + if in == nil { + return nil + } + out := new(ArgoCDNotifications) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDPrometheusSpec) DeepCopyInto(out *ArgoCDPrometheusSpec) { + *out = *in + in.Ingress.DeepCopyInto(&out.Ingress) + in.Route.DeepCopyInto(&out.Route) + if in.Size != nil { + in, out := &in.Size, &out.Size + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDPrometheusSpec. +func (in *ArgoCDPrometheusSpec) DeepCopy() *ArgoCDPrometheusSpec { + if in == nil { + return nil + } + out := new(ArgoCDPrometheusSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDRBACSpec) DeepCopyInto(out *ArgoCDRBACSpec) { + *out = *in + if in.DefaultPolicy != nil { + in, out := &in.DefaultPolicy, &out.DefaultPolicy + *out = new(string) + **out = **in + } + if in.Policy != nil { + in, out := &in.Policy, &out.Policy + *out = new(string) + **out = **in + } + if in.Scopes != nil { + in, out := &in.Scopes, &out.Scopes + *out = new(string) + **out = **in + } + if in.PolicyMatcherMode != nil { + in, out := &in.PolicyMatcherMode, &out.PolicyMatcherMode + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDRBACSpec. +func (in *ArgoCDRBACSpec) DeepCopy() *ArgoCDRBACSpec { + if in == nil { + return nil + } + out := new(ArgoCDRBACSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDRedisSpec) DeepCopyInto(out *ArgoCDRedisSpec) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDRedisSpec. +func (in *ArgoCDRedisSpec) DeepCopy() *ArgoCDRedisSpec { + if in == nil { + return nil + } + out := new(ArgoCDRedisSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDRepoSpec) DeepCopyInto(out *ArgoCDRepoSpec) { + *out = *in + if in.ExtraRepoCommandArgs != nil { + in, out := &in.ExtraRepoCommandArgs, &out.ExtraRepoCommandArgs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.ExecTimeout != nil { + in, out := &in.ExecTimeout, &out.ExecTimeout + *out = new(int) + **out = **in + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.InitContainers != nil { + in, out := &in.InitContainers, &out.InitContainers + *out = make([]v1.Container, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SidecarContainers != nil { + in, out := &in.SidecarContainers, &out.SidecarContainers + *out = make([]v1.Container, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDRepoSpec. +func (in *ArgoCDRepoSpec) DeepCopy() *ArgoCDRepoSpec { + if in == nil { + return nil + } + out := new(ArgoCDRepoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDRouteSpec) DeepCopyInto(out *ArgoCDRouteSpec) { + *out = *in + 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 + } + } + 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.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(routev1.TLSConfig) + **out = **in + } + if in.WildcardPolicy != nil { + in, out := &in.WildcardPolicy, &out.WildcardPolicy + *out = new(routev1.WildcardPolicyType) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDRouteSpec. +func (in *ArgoCDRouteSpec) DeepCopy() *ArgoCDRouteSpec { + if in == nil { + return nil + } + out := new(ArgoCDRouteSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDSSOSpec) DeepCopyInto(out *ArgoCDSSOSpec) { + *out = *in + if in.Dex != nil { + in, out := &in.Dex, &out.Dex + *out = new(ArgoCDDexSpec) + (*in).DeepCopyInto(*out) + } + if in.Keycloak != nil { + in, out := &in.Keycloak, &out.Keycloak + *out = new(ArgoCDKeycloakSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDSSOSpec. +func (in *ArgoCDSSOSpec) DeepCopy() *ArgoCDSSOSpec { + if in == nil { + return nil + } + out := new(ArgoCDSSOSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDServerAutoscaleSpec) DeepCopyInto(out *ArgoCDServerAutoscaleSpec) { + *out = *in + if in.HPA != nil { + in, out := &in.HPA, &out.HPA + *out = new(autoscalingv1.HorizontalPodAutoscalerSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDServerAutoscaleSpec. +func (in *ArgoCDServerAutoscaleSpec) DeepCopy() *ArgoCDServerAutoscaleSpec { + if in == nil { + return nil + } + out := new(ArgoCDServerAutoscaleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDServerGRPCSpec) DeepCopyInto(out *ArgoCDServerGRPCSpec) { + *out = *in + in.Ingress.DeepCopyInto(&out.Ingress) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDServerGRPCSpec. +func (in *ArgoCDServerGRPCSpec) DeepCopy() *ArgoCDServerGRPCSpec { + if in == nil { + return nil + } + out := new(ArgoCDServerGRPCSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDServerServiceSpec) DeepCopyInto(out *ArgoCDServerServiceSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDServerServiceSpec. +func (in *ArgoCDServerServiceSpec) DeepCopy() *ArgoCDServerServiceSpec { + if in == nil { + return nil + } + out := new(ArgoCDServerServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDServerSpec) DeepCopyInto(out *ArgoCDServerSpec) { + *out = *in + in.Autoscale.DeepCopyInto(&out.Autoscale) + in.GRPC.DeepCopyInto(&out.GRPC) + in.Ingress.DeepCopyInto(&out.Ingress) + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + in.Route.DeepCopyInto(&out.Route) + out.Service = in.Service + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ExtraCommandArgs != nil { + in, out := &in.ExtraCommandArgs, &out.ExtraCommandArgs + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDServerSpec. +func (in *ArgoCDServerSpec) DeepCopy() *ArgoCDServerSpec { + if in == nil { + return nil + } + out := new(ArgoCDServerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDSpec) DeepCopyInto(out *ArgoCDSpec) { + *out = *in + if in.ApplicationSet != nil { + in, out := &in.ApplicationSet, &out.ApplicationSet + *out = new(ArgoCDApplicationSet) + (*in).DeepCopyInto(*out) + } + in.Controller.DeepCopyInto(&out.Controller) + if in.ExtraConfig != nil { + in, out := &in.ExtraConfig, &out.ExtraConfig + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Grafana.DeepCopyInto(&out.Grafana) + in.HA.DeepCopyInto(&out.HA) + if in.Import != nil { + in, out := &in.Import, &out.Import + *out = new(ArgoCDImportSpec) + (*in).DeepCopyInto(*out) + } + out.InitialSSHKnownHosts = in.InitialSSHKnownHosts + if in.KustomizeVersions != nil { + in, out := &in.KustomizeVersions, &out.KustomizeVersions + *out = make([]KustomizeVersionSpec, len(*in)) + copy(*out, *in) + } + out.Monitoring = in.Monitoring + if in.NodePlacement != nil { + in, out := &in.NodePlacement, &out.NodePlacement + *out = new(ArgoCDNodePlacementSpec) + (*in).DeepCopyInto(*out) + } + in.Notifications.DeepCopyInto(&out.Notifications) + in.Prometheus.DeepCopyInto(&out.Prometheus) + in.RBAC.DeepCopyInto(&out.RBAC) + in.Redis.DeepCopyInto(&out.Redis) + in.Repo.DeepCopyInto(&out.Repo) + if in.ResourceHealthChecks != nil { + in, out := &in.ResourceHealthChecks, &out.ResourceHealthChecks + *out = make([]ResourceHealthCheck, len(*in)) + copy(*out, *in) + } + if in.ResourceIgnoreDifferences != nil { + in, out := &in.ResourceIgnoreDifferences, &out.ResourceIgnoreDifferences + *out = new(ResourceIgnoreDifference) + (*in).DeepCopyInto(*out) + } + if in.ResourceActions != nil { + in, out := &in.ResourceActions, &out.ResourceActions + *out = make([]ResourceAction, len(*in)) + copy(*out, *in) + } + in.Server.DeepCopyInto(&out.Server) + if in.SourceNamespaces != nil { + in, out := &in.SourceNamespaces, &out.SourceNamespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SSO != nil { + in, out := &in.SSO, &out.SSO + *out = new(ArgoCDSSOSpec) + (*in).DeepCopyInto(*out) + } + in.TLS.DeepCopyInto(&out.TLS) + if in.Banner != nil { + in, out := &in.Banner, &out.Banner + *out = new(Banner) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDSpec. +func (in *ArgoCDSpec) DeepCopy() *ArgoCDSpec { + if in == nil { + return nil + } + out := new(ArgoCDSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDStatus) DeepCopyInto(out *ArgoCDStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDStatus. +func (in *ArgoCDStatus) DeepCopy() *ArgoCDStatus { + if in == nil { + return nil + } + out := new(ArgoCDStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArgoCDTLSSpec) DeepCopyInto(out *ArgoCDTLSSpec) { + *out = *in + out.CA = in.CA + if in.InitialCerts != nil { + in, out := &in.InitialCerts, &out.InitialCerts + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDTLSSpec. +func (in *ArgoCDTLSSpec) DeepCopy() *ArgoCDTLSSpec { + if in == nil { + return nil + } + out := new(ArgoCDTLSSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Banner) DeepCopyInto(out *Banner) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Banner. +func (in *Banner) DeepCopy() *Banner { + if in == nil { + return nil + } + out := new(Banner) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IgnoreDifferenceCustomization) DeepCopyInto(out *IgnoreDifferenceCustomization) { + *out = *in + if in.JqPathExpressions != nil { + in, out := &in.JqPathExpressions, &out.JqPathExpressions + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.JsonPointers != nil { + in, out := &in.JsonPointers, &out.JsonPointers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ManagedFieldsManagers != nil { + in, out := &in.ManagedFieldsManagers, &out.ManagedFieldsManagers + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IgnoreDifferenceCustomization. +func (in *IgnoreDifferenceCustomization) DeepCopy() *IgnoreDifferenceCustomization { + if in == nil { + return nil + } + out := new(IgnoreDifferenceCustomization) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KustomizeVersionSpec) DeepCopyInto(out *KustomizeVersionSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeVersionSpec. +func (in *KustomizeVersionSpec) DeepCopy() *KustomizeVersionSpec { + if in == nil { + return nil + } + out := new(KustomizeVersionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceAction) DeepCopyInto(out *ResourceAction) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceAction. +func (in *ResourceAction) DeepCopy() *ResourceAction { + if in == nil { + return nil + } + out := new(ResourceAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceHealthCheck) DeepCopyInto(out *ResourceHealthCheck) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceHealthCheck. +func (in *ResourceHealthCheck) DeepCopy() *ResourceHealthCheck { + if in == nil { + return nil + } + out := new(ResourceHealthCheck) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceIdentifiers) DeepCopyInto(out *ResourceIdentifiers) { + *out = *in + in.Customization.DeepCopyInto(&out.Customization) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceIdentifiers. +func (in *ResourceIdentifiers) DeepCopy() *ResourceIdentifiers { + if in == nil { + return nil + } + out := new(ResourceIdentifiers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceIgnoreDifference) DeepCopyInto(out *ResourceIgnoreDifference) { + *out = *in + if in.All != nil { + in, out := &in.All, &out.All + *out = new(IgnoreDifferenceCustomization) + (*in).DeepCopyInto(*out) + } + if in.ResourceIdentifiers != nil { + in, out := &in.ResourceIdentifiers, &out.ResourceIdentifiers + *out = make([]ResourceIdentifiers, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceIgnoreDifference. +func (in *ResourceIgnoreDifference) DeepCopy() *ResourceIgnoreDifference { + if in == nil { + return nil + } + out := new(ResourceIgnoreDifference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSHHostsSpec) DeepCopyInto(out *SSHHostsSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSHHostsSpec. +func (in *SSHHostsSpec) DeepCopy() *SSHHostsSpec { + if in == nil { + return nil + } + out := new(SSHHostsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookServerSpec) DeepCopyInto(out *WebhookServerSpec) { + *out = *in + in.Ingress.DeepCopyInto(&out.Ingress) + in.Route.DeepCopyInto(&out.Route) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookServerSpec. +func (in *WebhookServerSpec) DeepCopy() *WebhookServerSpec { + if in == nil { + return nil + } + out := new(WebhookServerSpec) + in.DeepCopyInto(out) + return out +} diff --git a/bundle/manifests/argocd-operator-webhook-service_v1_service.yaml b/bundle/manifests/argocd-operator-webhook-service_v1_service.yaml new file mode 100644 index 000000000..f5dda7bc9 --- /dev/null +++ b/bundle/manifests/argocd-operator-webhook-service_v1_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + name: argocd-operator-webhook-service +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: argocd-operator +status: + loadBalancer: {} diff --git a/bundle/manifests/argocd-operator.clusterserviceversion.yaml b/bundle/manifests/argocd-operator.clusterserviceversion.yaml index f21e476df..a34457ca3 100644 --- a/bundle/manifests/argocd-operator.clusterserviceversion.yaml +++ b/bundle/manifests/argocd-operator.clusterserviceversion.yaml @@ -125,6 +125,94 @@ metadata: "spec": { "argocd": "argocd-sample" } + }, + { + "apiVersion": "argoproj.io/v1beta1", + "kind": "ArgoCD", + "metadata": { + "name": "argocd-sample" + }, + "spec": { + "controller": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "2048Mi" + }, + "requests": { + "cpu": "250m", + "memory": "1024Mi" + } + } + }, + "ha": { + "enabled": false, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "redis": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "repo": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "512Mi" + }, + "requests": { + "cpu": "250m", + "memory": "256Mi" + } + } + }, + "server": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "125m", + "memory": "128Mi" + } + }, + "route": { + "enabled": true + } + }, + "sso": { + "dex": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "provider": "dex" + } + } } ] capabilities: Deep Insights @@ -216,29 +304,638 @@ spec: path: argocd x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - - description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. - displayName: Schedule - path: schedule + - description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + displayName: Schedule + path: schedule + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Storage defines the storage configuration options. + displayName: Storage + path: storage + statusDescriptors: + - description: 'Phase is a simple, high-level summary of where the ArgoCDExport + is in its lifecycle. There are five possible phase values: Pending: The + ArgoCDExport has been accepted by the Kubernetes system, but one or more + of the required resources have not been created. Running: All of the containers + for the ArgoCDExport are still running, or in the process of starting or + restarting. Succeeded: All containers for the ArgoCDExport have terminated + in success, and will not be restarted. Failed: At least one container has + terminated in failure, either exited with non-zero status or was terminated + by the system. Unknown: For some reason the state of the ArgoCDExport could + not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1alpha1 + - description: ArgoCD is the Schema for the argocds API + displayName: Argo CD + kind: ArgoCD + name: argocds.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1alpha1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: ApplicationInstanceLabelKey is the key name where Argo CD injects + the app name as a tracking label. + displayName: Application Instance Label Key' + path: applicationInstanceLabelKey + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: applicationSet.webhookServer.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: applicationSet.webhookServer.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: applicationSet.webhookServer.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ConfigManagementPlugins is used to specify additional config + management plugins. + displayName: Config Management Plugins' + path: configManagementPlugins + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Operation is the number of application operation processors. + displayName: Operation Processor Count' + path: controller.processors.operation + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Status is the number of application status processors. + displayName: Status Processor Count' + path: controller.processors.status + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resources defines the Compute Resources required by the container + for the Application Controller. + displayName: Resource Requirements' + path: controller.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Config is the dex connector configuration. + displayName: Configuration + path: dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: GAAnonymizeUsers toggles user IDs being hashed before sending + to google analytics. + displayName: Google Analytics Anonymize Users' + path: gaAnonymizeUsers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: GATrackingID is the google analytics tracking ID to use. + displayName: Google Analytics Tracking ID' + path: gaTrackingID + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Grafana support globally for ArgoCD. + displayName: Enabled + path: grafana.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: grafana.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Grafana container image. + displayName: Image + path: grafana.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: grafana.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Grafana. + displayName: Resource Requirements' + path: grafana.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: grafana.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Grafana Deployment. + displayName: Size + path: grafana.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Version is the Grafana container image tag. + displayName: Version + path: grafana.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle HA support globally for Argo CD. + displayName: Enabled + path: ha.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: HelpChatText is the text for getting chat help, defaults to "Chat + now!" + displayName: Help Chat Text' + path: helpChatText + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: HelpChatURL is the URL for getting chat help, this will typically + be your Slack channel for support. + displayName: Help Chat URL' + path: helpChatURL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Image is the ArgoCD container image for all ArgoCD components. + displayName: Image + path: image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of an ArgoCDExport from which to import data. + displayName: Name + path: import.name + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: Namespace for the ArgoCDExport, defaults to the same namespace + as the ArgoCD. + displayName: Namespace + path: import.namespace + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: InitialRepositories to configure Argo CD with upon creation of + the cluster. + displayName: Initial Repositories' + path: initialRepositories + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: KustomizeVersions is a listing of configured versions of Kustomize + to be made available within ArgoCD. + displayName: Kustomize Build Options' + path: kustomizeVersions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: OIDCConfig is the OIDC configuration as an alternative to dex. + displayName: OIDC Config' + path: oidcConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Prometheus support globally for ArgoCD. + displayName: Enabled + path: prometheus.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: prometheus.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: prometheus.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: prometheus.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Prometheus StatefulSet. + displayName: Size + path: prometheus.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: DefaultPolicy is the name of the default role which Argo CD will + falls back to, when authorizing API requests (optional). If omitted or empty, + users may be still be able to login, but will see no apps, projects, etc... + displayName: Default Policy' + path: rbac.defaultPolicy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Policy is CSV containing user-defined RBAC policies and role + definitions. Policy rules are in the form: p, subject, resource, action, + object, effect Role definitions and bindings are in the form: g, subject, + inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + displayName: Policy + path: rbac.policy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Scopes controls which OIDC scopes to examine during rbac enforcement + (in addition to `sub` scope). If omitted, defaults to: ''[groups]''.' + displayName: Scopes + path: rbac.scopes + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Redis container image. + displayName: Image + path: redis.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: redis.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Redis container image tag. + displayName: Version + path: redis.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: repo.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: ResourceActions customizes resource action behavior. + displayName: Resource Action Customizations' + path: resourceActions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'ResourceCustomizations customizes resource behavior. Keys are + in the form: group/Kind. Please note that this is being deprecated in favor + of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + displayName: Resource Customizations' + path: resourceCustomizations + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceExclusions is used to completely ignore entire classes + of resource group/kinds. + displayName: Resource Exclusions' + path: resourceExclusions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceHealthChecks customizes resource health check behavior. + displayName: Resource Health Check Customizations' + path: resourceHealthChecks x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - - description: Storage defines the storage configuration options. - displayName: Storage - path: storage + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceIgnoreDifferences customizes resource ignore difference + behavior. + displayName: Resource Ignore Difference Customizations' + path: resourceIgnoreDifferences + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceTrackingMethod defines how Argo CD should track resources + that it manages + displayName: Resource Tracking Method' + path: resourceTrackingMethod + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle autoscaling support for the Argo CD Server + component. + displayName: Autoscale Enabled' + path: server.autoscale.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: GRPC Host + path: server.grpc.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Ingress defines the desired state for the Argo CD Server GRPC + Ingress. + displayName: GRPC Ingress Enabled' + path: server.grpc.ingress + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.grpc.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: server.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Insecure toggles the insecure flag. + displayName: Insecure + path: server.insecure + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for the Argo CD server component. + displayName: Resource Requirements' + path: server.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: server.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Type is the ServiceType to use for the Service resource. + displayName: Service Type' + path: server.service.type + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Config is the dex connector configuration. + displayName: Configuration + path: sso.dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: sso.dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: sso.dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: sso.dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: sso.dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: StatusBadgeEnabled toggles application status badge feature. + displayName: Status Badge Enabled' + path: statusBadgeEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: UsersAnonymousEnabled toggles anonymous user access. The anonymous + users get default role permissions specified argocd-rbac-cm. + displayName: Anonymous Users Enabled' + path: usersAnonymousEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Version is the tag to use with the ArgoCD container image for + all ArgoCD components. + displayName: Version + path: version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text statusDescriptors: - - description: 'Phase is a simple, high-level summary of where the ArgoCDExport - is in its lifecycle. There are five possible phase values: Pending: The - ArgoCDExport has been accepted by the Kubernetes system, but one or more - of the required resources have not been created. Running: All of the containers - for the ArgoCDExport are still running, or in the process of starting or - restarting. Succeeded: All containers for the ArgoCDExport have terminated - in success, and will not be restarted. Failed: At least one container has - terminated in failure, either exited with non-zero status or was terminated - by the system. Unknown: For some reason the state of the ArgoCDExport could - not be obtained.' + - description: 'ApplicationController is a simple, high-level summary of where + the Argo CD application controller component is in its lifecycle. There + are four possible ApplicationController values: Pending: The Argo CD application + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD application controller component are in + a Ready state. Failed: At least one of the Argo CD application controller + component Pods had a failure. Unknown: The state of the Argo CD application + controller component could not be obtained.' + displayName: ApplicationController + path: applicationController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'ApplicationSetController is a simple, high-level summary of + where the Argo CD applicationSet controller component is in its lifecycle. + There are four possible ApplicationSetController values: Pending: The Argo + CD applicationSet controller component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD applicationSet controller + component are in a Ready state. Failed: At least one of the Argo CD applicationSet + controller component Pods had a failure. Unknown: The state of the Argo + CD applicationSet controller component could not be obtained.' + displayName: ApplicationSetController + path: applicationSetController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'NotificationsController is a simple, high-level summary of where + the Argo CD notifications controller component is in its lifecycle. There + are four possible NotificationsController values: Pending: The Argo CD notifications + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD notifications controller component are + in a Ready state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD notifications + controller component could not be obtained.' + displayName: NotificationsController + path: notificationsController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Phase is a simple, high-level summary of where the ArgoCD is + in its lifecycle. There are four possible phase values: Pending: The ArgoCD + has been accepted by the Kubernetes system, but one or more of the required + resources have not been created. Available: All of the resources for the + ArgoCD are ready. Failed: At least one resource has experienced a failure. + Unknown: The state of the ArgoCD phase could not be obtained.' displayName: Phase path: phase x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Redis is a simple, high-level summary of where the Argo CD Redis + component is in its lifecycle. There are four possible redis values: Pending: + The Argo CD Redis component has been accepted by the Kubernetes system, + but one or more of the required resources have not been created. Running: + All of the required Pods for the Argo CD Redis component are in a Ready + state. Failed: At least one of the Argo CD Redis component Pods had a failure. + Unknown: The state of the Argo CD Redis component could not be obtained.' + displayName: Redis + path: redis + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Repo is a simple, high-level summary of where the Argo CD Repo + component is in its lifecycle. There are four possible repo values: Pending: + The Argo CD Repo component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Repo component are in a Ready state. + Failed: At least one of the Argo CD Repo component Pods had a failure. + Unknown: The state of the Argo CD Repo component could not be obtained.' + displayName: Repo + path: repo + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Server is a simple, high-level summary of where the Argo CD + server component is in its lifecycle. There are four possible server values: + Pending: The Argo CD server component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD server component are in + a Ready state. Failed: At least one of the Argo CD server component Pods + had a failure. Unknown: The state of the Argo CD server component could + not be obtained.' + displayName: Server + path: server + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) + component is in its lifecycle. There are four possible sso values: Pending: + The Argo CD SSO component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD SSO component are in a Ready state. + Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: + The state of the Argo CD SSO component could not be obtained.' + displayName: SSO + path: sso + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text version: v1alpha1 - description: ArgoCD is the Schema for the argocds API displayName: Argo CD @@ -247,7 +944,7 @@ spec: resources: - kind: ArgoCD name: "" - version: v1alpha1 + version: v1beta1 - kind: ArgoCDExport name: "" version: v1alpha1 @@ -816,7 +1513,7 @@ spec: path: sso x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - version: v1alpha1 + version: v1beta1 description: | ## Overview @@ -1050,6 +1747,8 @@ spec: valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: ENABLE_CONVERSION_WEBHOOK + value: "true" image: quay.io/argoprojlabs/argocd-operator:v0.8.0 livenessProbe: httpGet: @@ -1058,6 +1757,10 @@ spec: initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP readinessProbe: httpGet: path: /readyz @@ -1112,9 +1815,9 @@ spec: serviceAccountName: argocd-operator-controller-manager strategy: deployment installModes: - - supported: true + - supported: false type: OwnNamespace - - supported: true + - supported: false type: SingleNamespace - supported: false type: MultiNamespace @@ -1138,3 +1841,16 @@ spec: name: Argo CD Community replaces: argocd-operator.v0.7.0 version: 0.8.0 + webhookdefinitions: + - admissionReviewVersions: + - v1alpha1 + - v1beta1 + containerPort: 443 + conversionCRDs: + - argocds.argoproj.io + deploymentName: argocd-operator-controller-manager + generateName: cargocds.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index 87d7c51d6..eb6530c06 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -6,6 +6,17 @@ metadata: creationTimestamp: null name: argocds.argoproj.io spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: argocd-operator-webhook-service + namespace: argocd-operator-system + path: /convert + conversionReviewVersions: + - v1alpha1 + - v1beta1 group: argoproj.io names: kind: ArgoCD @@ -14,7 +25,6451 @@ spec: singular: argocd scope: Namespaced versions: - - name: v1alpha1 + - deprecated: true + deprecationWarning: ArgoCD v1alpha1 is deprecated, please use v1beta1 instead. + name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCD is the Schema for the argocds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDSpec defines the desired state of ArgoCD + properties: + applicationInstanceLabelKey: + description: ApplicationInstanceLabelKey is the key name where Argo + CD injects the app name as a tracking label. + type: string + applicationSet: + description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet + controller should be installed. + properties: + env: + description: Env lets you specify environment for applicationSet + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: ExtraCommandArgs allows users to pass command line + arguments to ApplicationSet controller. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the Argo CD ApplicationSet image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for ApplicationSet. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD ApplicationSet image tag. + (optional) + type: string + webhookServer: + description: WebhookServerSpec defines the options for the ApplicationSet + Webhook Server component. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + use for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the + Route resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the + contents of the ca certificate of the final destination. When + using reencrypt termination this file should be + provided in order to have routers use it for health + checks on the secure connection. If this field is + not specified, the router may provide its own destination + CA and perform hostname validation using the short + service name (service.namespace.svc), which allows + infrastructure generated certificates to automatically + verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to + a route. While each router may make its own decisions + on which ports to expose, this is normally port + 80. \n * Allow - traffic is sent to the server on + the insecure port (default) * Disable - no traffic + is allowed on the insecure port. * Redirect - clients + are redirected to the secure port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + type: object + type: object + banner: + description: Banner defines an additional banner to be displayed in + Argo CD UI + properties: + content: + description: Content defines the banner message content to display + type: string + url: + description: URL defines an optional URL to be used as banner + message link + type: string + required: + - content + type: object + configManagementPlugins: + description: ConfigManagementPlugins is used to specify additional + config management plugins. + type: string + controller: + description: Controller defines the Application Controller options + for ArgoCD. + properties: + appSync: + description: "AppSync is used to control the sync frequency, by + default the ArgoCD controller polls Git every 3m. \n Set this + to a duration, e.g. 10m or 600s to control the synchronisation + frequency." + type: string + env: + description: Env lets you specify environment for application + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + logFormat: + description: LogFormat refers to the log format used by the Application + Controller component. Defaults to ArgoCDDefaultLogFormat if + not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level used by the Application + Controller component. Defaults to ArgoCDDefaultLogLevel if not + configured. Valid options are debug, info, error, and warn. + type: string + parallelismLimit: + description: ParallelismLimit defines the limit for parallel kubectl + operations + format: int32 + type: integer + processors: + description: Processors contains the options for the Application + Controller processors. + properties: + operation: + description: Operation is the number of application operation + processors. + format: int32 + type: integer + status: + description: Status is the number of application status processors. + format: int32 + type: integer + type: object + resources: + description: Resources defines the Compute Resources required + by the container for the Application Controller. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + sharding: + description: Sharding contains the options for the Application + Controller sharding configuration. + properties: + clustersPerShard: + description: ClustersPerShard defines the maximum number of + clusters managed by each argocd shard + format: int32 + minimum: 1 + type: integer + dynamicScalingEnabled: + description: DynamicScalingEnabled defines whether dynamic + scaling should be enabled for Application Controller component + type: boolean + enabled: + description: Enabled defines whether sharding should be enabled + on the Application Controller component. + type: boolean + maxShards: + description: MaxShards defines the maximum number of shards + at any given point + format: int32 + type: integer + minShards: + description: MinShards defines the minimum number of shards + at any given point + format: int32 + minimum: 1 + type: integer + replicas: + description: Replicas defines the number of replicas to run + in the Application controller shard. + format: int32 + type: integer + type: object + type: object + dex: + description: Deprecated field. Support dropped in v1beta1 version. + Dex defines the Dex server options for ArgoCD. + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must be a + member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + disableAdmin: + description: DisableAdmin will disable the admin user. + type: boolean + extraConfig: + additionalProperties: + type: string + description: "ExtraConfig can be used to add fields to Argo CD configmap + that are not supported by Argo CD CRD. \n Note: ExtraConfig takes + precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` + = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. + In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] + = true." + type: object + gaAnonymizeUsers: + description: GAAnonymizeUsers toggles user IDs being hashed before + sending to google analytics. + type: boolean + gaTrackingID: + description: GATrackingID is the google analytics tracking ID to use. + type: string + grafana: + description: Grafana defines the Grafana server options for ArgoCD. + properties: + enabled: + description: Enabled will toggle Grafana support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + image: + description: Image is the Grafana container image. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + resources: + description: Resources defines the Compute Resources required + by the container for Grafana. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Grafana Deployment. + format: int32 + type: integer + version: + description: Version is the Grafana container image tag. + type: string + required: + - enabled + type: object + ha: + description: HA options for High Availability support for the Redis + component. + properties: + enabled: + description: Enabled will toggle HA support globally for Argo + CD. + type: boolean + redisProxyImage: + description: RedisProxyImage is the Redis HAProxy container image. + type: string + redisProxyVersion: + description: RedisProxyVersion is the Redis HAProxy container + image tag. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for HA. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - enabled + type: object + helpChatText: + description: HelpChatText is the text for getting chat help, defaults + to "Chat now!" + type: string + helpChatURL: + description: HelpChatURL is the URL for getting chat help, this will + typically be your Slack channel for support. + type: string + image: + description: Image is the ArgoCD container image for all ArgoCD components. + type: string + import: + description: Import is the import/restore options for ArgoCD. + properties: + name: + description: Name of an ArgoCDExport from which to import data. + type: string + namespace: + description: Namespace for the ArgoCDExport, defaults to the same + namespace as the ArgoCD. + type: string + required: + - name + type: object + initialRepositories: + description: InitialRepositories to configure Argo CD with upon creation + of the cluster. + type: string + initialSSHKnownHosts: + description: InitialSSHKnownHosts defines the SSH known hosts data + upon creation of the cluster for connecting Git repositories via + SSH. + properties: + excludedefaulthosts: + description: ExcludeDefaultHosts describes whether you would like + to include the default list of SSH Known Hosts provided by ArgoCD. + type: boolean + keys: + description: Keys describes a custom set of SSH Known Hosts that + you would like to have included in your ArgoCD server. + type: string + type: object + kustomizeBuildOptions: + description: KustomizeBuildOptions is used to specify build options/parameters + to use with `kustomize build`. + type: string + kustomizeVersions: + description: KustomizeVersions is a listing of configured versions + of Kustomize to be made available within ArgoCD. + items: + description: KustomizeVersionSpec is used to specify information + about a kustomize version to be used within ArgoCD. + properties: + path: + description: Path is the path to a configured kustomize version + on the filesystem of your repo server. + type: string + version: + description: Version is a configured kustomize version in the + format of vX.Y.Z + type: string + type: object + type: array + monitoring: + description: Monitoring defines whether workload status monitoring + configuration for this instance. + properties: + enabled: + description: Enabled defines whether workload status monitoring + is enabled for this instance or not + type: boolean + required: + - enabled + type: object + nodePlacement: + description: NodePlacement defines NodeSelectors and Taints for Argo + CD workloads + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a field of PodSpec, it is a map of + key value pairs used for node selection + type: object + tolerations: + description: Tolerations allow the pods to schedule onto nodes + with matching taints + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + notifications: + description: Notifications defines whether the Argo CD Notifications + controller should be installed. + properties: + enabled: + description: Enabled defines whether argocd-notifications controller + should be deployed or not + type: boolean + env: + description: Env let you specify environment variables for Notifications + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Image is the Argo CD Notifications image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas to run for + notifications-controller + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Argo CD Notifications. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD Notifications image tag. (optional) + type: string + required: + - enabled + type: object + oidcConfig: + description: OIDCConfig is the OIDC configuration as an alternative + to dex. + type: string + prometheus: + description: Prometheus defines the Prometheus server options for + ArgoCD. + properties: + enabled: + description: Enabled will toggle Prometheus support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Prometheus StatefulSet. + format: int32 + type: integer + required: + - enabled + type: object + rbac: + description: RBAC defines the RBAC configuration for Argo CD. + properties: + defaultPolicy: + description: DefaultPolicy is the name of the default role which + Argo CD will falls back to, when authorizing API requests (optional). + If omitted or empty, users may be still be able to login, but + will see no apps, projects, etc... + type: string + policy: + description: 'Policy is CSV containing user-defined RBAC policies + and role definitions. Policy rules are in the form: p, subject, + resource, action, object, effect Role definitions and bindings + are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + type: string + policyMatcherMode: + description: PolicyMatcherMode configures the matchers function + mode for casbin. There are two options for this, 'glob' for + glob matcher or 'regex' for regex matcher. + type: string + scopes: + description: 'Scopes controls which OIDC scopes to examine during + rbac enforcement (in addition to `sub` scope). If omitted, defaults + to: ''[groups]''.' + type: string + type: object + redis: + description: Redis defines the Redis server options for ArgoCD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the redis server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + disableTLSVerification: + description: DisableTLSVerification defines whether redis server + API should be accessed using strict TLS validation + type: boolean + image: + description: Image is the Redis container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Redis container image tag. + type: string + type: object + repo: + description: Repo defines the repo server options for Argo CD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the repo server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + env: + description: Env lets you specify environment for repo server + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + execTimeout: + description: ExecTimeout specifies the timeout in seconds for + tool execution + type: integer + extraRepoCommandArgs: + description: Extra Command arguments allows users to pass command + line arguments to repo server workload. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraRepoCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the ArgoCD Repo Server container image. + type: string + initContainers: + description: InitContainers defines the list of initialization + containers for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + logFormat: + description: LogFormat describes the log format that should be + used by the Repo Server. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not + set. Valid options are debug, info, error, and warn. + type: string + mountsatoken: + description: MountSAToken describes whether you would like to + have the Repo server mount the service account token + type: boolean + replicas: + description: Replicas defines the number of replicas for argocd-repo-server. + Value should be greater than or equal to 0. Default is nil. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceaccount: + description: ServiceAccount defines the ServiceAccount user that + you would like the Repo server to use + type: string + sidecarContainers: + description: SidecarContainers defines the list of sidecar containers + for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + verifytls: + description: VerifyTLS defines whether repo server API should + be accessed using strict TLS validation + type: boolean + version: + description: Version is the ArgoCD Repo Server container image + tag. + type: string + volumeMounts: + description: VolumeMounts adds volumeMounts to the repo server + container + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes adds volumes to the repo server deployment + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force and set the ReadOnly + property in VolumeMounts to "true". If omitted, the + default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent disk resource + in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, Read Only, Read + Write.' + type: string + diskName: + description: The Name of the data disk in the blob storage + type: string + diskURI: + description: The URI the data disk in the blob storage + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + kind: + description: 'Expected values Shared: multiple blob + disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that contains Azure + Storage Account Name and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'Required: Monitors is a collection of + Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the mounted root, rather + than the full Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile is the path to key + ring for User, default is /etc/ceph/user.secret More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef is reference to the + authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'Optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to a secret object containing + parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the ConfigMap, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its keys + must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: Driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: Filesystem type to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: Specifies a read-only configuration for + the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage medium should back + this directory. The default is "" which means to use + the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'Total amount of local storage required + for this EmptyDir volume. The size limit is also applicable + for memory medium. The maximum usage on memory medium + EmptyDir would be the minimum value between the SizeLimit + specified here and the sum of memory limits of all + containers in a pod. The default is nil which means + that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "Ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'AccessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify + either: * An existing VolumeSnapshot object + (snapshot.storage.k8s.io/VolumeSnapshot) * + An existing PVC (PersistentVolumeClaim) If + the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. If the AnyVolumeDataSource + feature gate is enabled, this field will always + have the same contents as the DataSourceRef + field.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'Specifies the object from which + to populate the volume with data, if a non-empty + volume is desired. This may be any local object + from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this + field is specified, volume binding will only + succeed if the type of the specified object + matches some installed volume populator or + dynamic provisioner. This field will replace + the functionality of the DataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, both fields (DataSource and + DataSourceRef) will be set to the same value + automatically if one of them is empty and + the other is non-empty. There are two important + differences between DataSource and DataSourceRef: + * While DataSource only allows two specific + types of objects, DataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While DataSource ignores disallowed + values (dropping them), DataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. (Alpha) Using this field + requires the AnyVolumeDataSource feature gate + to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: A label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required + by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: VolumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: FC represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: Driver is the name of the driver to use + for this volume. + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". The default filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command options if any.' + type: object + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef is reference to the + secret object containing sensitive information to + pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the + plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored as metadata + -> name on the dataset for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD resource in GCE. + Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. Must not contain + or start with '..'. If '.' is supplied, the volume + directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator Name. If initiatorName + is specified with iscsiInterface simultaneously, new + iSCSI interface : will + be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iSCSI Interface Name that uses an iSCSI + transport. Defaults to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. The portal is + either an IP or ip_addr:port if the port is other + than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI target and initiator + authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. The Portal is either + an IP or ip_addr:port if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + pdID: + description: ID that identifies Photon Controller persistent + disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: FSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources secrets, configmaps, + and downward API + properties: + defaultMode: + description: Mode bits used to set permissions on created + files by default. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. Directories within the + path are not affected by this setting. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: information about the configMap data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + downwardAPI: + description: information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about the secret data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + type: object + serviceAccountToken: + description: information about the serviceAccountToken + data to project + properties: + audience: + description: Audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: Path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: Quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: Group to map volume access to Default is + no group + type: string + readOnly: + description: ReadOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: Tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: Volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph monitors. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. Default is rbd. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'The rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: The host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO Protection Domain + for the configured storage. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: Indicates whether the storage for a volume + should be ThickProvisioned or ThinProvisioned. Default + is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool associated with + the protection domain. + type: string + system: + description: The name of the storage system as configured + in ScaleIO. + type: string + volumeName: + description: The name of a volume already created in + the ScaleIO system that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start + with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret or its keys + must be defined + type: boolean + secretName: + description: 'Name of the secret in the pod''s namespace + to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + storagePolicyID: + description: Storage Policy Based Management (SPBM) + profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based Management (SPBM) + profile name. + type: string + volumePath: + description: Path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + repositoryCredentials: + description: RepositoryCredentials are the Git pull credentials to + configure Argo CD with upon creation of the cluster. + type: string + resourceActions: + description: ResourceActions customizes resource action behavior. + items: + description: Resource Customization for custom action + properties: + action: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceCustomizations: + description: 'ResourceCustomizations customizes resource behavior. + Keys are in the form: group/Kind. Please note that this is being + deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' + type: string + resourceExclusions: + description: ResourceExclusions is used to completely ignore entire + classes of resource group/kinds. + type: string + resourceHealthChecks: + description: ResourceHealthChecks customizes resource health check + behavior. + items: + description: Resource Customization for custom health check + properties: + check: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceIgnoreDifferences: + description: ResourceIgnoreDifferences customizes resource ignore + difference behavior. + properties: + all: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + resourceIdentifiers: + items: + description: Resource Customization fields for ignore difference + properties: + customization: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + group: + type: string + kind: + type: string + type: object + type: array + type: object + resourceInclusions: + description: ResourceInclusions is used to only include specific group/kinds + in the reconciliation process. + type: string + resourceTrackingMethod: + description: ResourceTrackingMethod defines how Argo CD should track + resources that it manages + type: string + server: + description: Server defines the options for the ArgoCD Server component. + properties: + autoscale: + description: Autoscale defines the autoscale options for the Argo + CD Server component. + properties: + enabled: + description: Enabled will toggle autoscaling support for the + Argo CD Server component. + type: boolean + hpa: + description: HPA defines the HorizontalPodAutoscaler options + for the Argo CD Server component. + properties: + maxReplicas: + description: upper limit for the number of pods that can + be set by the autoscaler; cannot be smaller than MinReplicas. + format: int32 + type: integer + minReplicas: + description: minReplicas is the lower limit for the number + of replicas to which the autoscaler can scale down. It + defaults to 1 pod. minReplicas is allowed to be 0 if + the alpha feature gate HPAScaleToZero is enabled and + at least one Object or External metric is configured. Scaling + is active as long as at least one metric value is available. + format: int32 + type: integer + scaleTargetRef: + description: reference to scaled resource; horizontal + pod autoscaler will learn the current resource consumption + and will set the desired number of pods by using its + Scale subresource. + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + type: string + name: + description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + required: + - kind + - name + type: object + targetCPUUtilizationPercentage: + description: target average CPU utilization (represented + as a percentage of requested CPU) over all the pods; + if not specified the default autoscaling policy will + be used. + format: int32 + type: integer + required: + - maxReplicas + - scaleTargetRef + type: object + required: + - enabled + type: object + env: + description: Env lets you specify environment for API server pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: Extra Command arguments that would append to the + Argo CD server command. ExtraCommandArgs will not be added, + if one of these commands is already part of the server command + with same or different value. + items: + type: string + type: array + grpc: + description: GRPC defines the state for the Argo CD Server GRPC + options. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for the Argo + CD Server GRPC Ingress. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + type: object + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + insecure: + description: Insecure toggles the insecure flag. + type: boolean + logFormat: + description: LogFormat refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if + not set. Valid options are debug, info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas for argocd-server. + Default is nil. Value should be greater than or equal to 0. + Value will be ignored if Autoscaler is enabled. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for the Argo CD server component. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + service: + description: Service defines the options for the Service backing + the ArgoCD Server component. + properties: + type: + description: Type is the ServiceType to use for the Service + resource. + type: string + required: + - type + type: object + type: object + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sso: + description: SSO defines the Single Sign-on configuration for Argo + CD + properties: + dex: + description: Dex contains the configuration for Argo CD dex authentication + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must + be a member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + image: + description: Deprecated field. Support dropped in v1beta1 version. + Image is the SSO container image. + type: string + keycloak: + description: Keycloak contains the configuration for Argo CD keycloak + authentication + properties: + image: + description: Image is the Keycloak container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Keycloak. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + rootCA: + description: Custom root CA certificate for communicating + with the Keycloak OIDC provider + type: string + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the Keycloak container image tag. + type: string + type: object + provider: + description: Provider installs and configures the given SSO Provider + with Argo CD. + type: string + resources: + description: Deprecated field. Support dropped in v1beta1 version. + Resources defines the Compute Resources required by the container + for SSO. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + verifyTLS: + description: Deprecated field. Support dropped in v1beta1 version. + VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Deprecated field. Support dropped in v1beta1 version. + Version is the SSO container image tag. + type: string + type: object + statusBadgeEnabled: + description: StatusBadgeEnabled toggles application status badge feature. + type: boolean + tls: + description: TLS defines the TLS options for ArgoCD. + properties: + ca: + description: CA defines the CA options. + properties: + configMapName: + description: ConfigMapName is the name of the ConfigMap containing + the CA Certificate. + type: string + secretName: + description: SecretName is the name of the Secret containing + the CA Certificate and Key. + type: string + type: object + initialCerts: + additionalProperties: + type: string + description: InitialCerts defines custom TLS certificates upon + creation of the cluster for connecting Git repositories via + HTTPS. + type: object + type: object + usersAnonymousEnabled: + description: UsersAnonymousEnabled toggles anonymous user access. + The anonymous users get default role permissions specified argocd-rbac-cm. + type: boolean + version: + description: Version is the tag to use with the ArgoCD container image + for all ArgoCD components. + type: string + type: object + status: + description: ArgoCDStatus defines the observed state of ArgoCD + properties: + applicationController: + description: 'ApplicationController is a simple, high-level summary + of where the Argo CD application controller component is in its + lifecycle. There are four possible ApplicationController values: + Pending: The Argo CD application controller component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD application controller component are in a Ready state. Failed: + At least one of the Argo CD application controller component Pods + had a failure. Unknown: The state of the Argo CD application controller + component could not be obtained.' + type: string + applicationSetController: + description: 'ApplicationSetController is a simple, high-level summary + of where the Argo CD applicationSet controller component is in its + lifecycle. There are four possible ApplicationSetController values: + Pending: The Argo CD applicationSet controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD applicationSet controller component are in a Ready + state. Failed: At least one of the Argo CD applicationSet controller + component Pods had a failure. Unknown: The state of the Argo CD + applicationSet controller component could not be obtained.' + type: string + host: + description: Host is the hostname of the Ingress. + type: string + notificationsController: + description: 'NotificationsController is a simple, high-level summary + of where the Argo CD notifications controller component is in its + lifecycle. There are four possible NotificationsController values: + Pending: The Argo CD notifications controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD notifications controller component are in a Ready + state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD + notifications controller component could not be obtained.' + type: string + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCD + is in its lifecycle. There are four possible phase values: Pending: + The ArgoCD has been accepted by the Kubernetes system, but one or + more of the required resources have not been created. Available: + All of the resources for the ArgoCD are ready. Failed: At least + one resource has experienced a failure. Unknown: The state of the + ArgoCD phase could not be obtained.' + type: string + redis: + description: 'Redis is a simple, high-level summary of where the Argo + CD Redis component is in its lifecycle. There are four possible + redis values: Pending: The Argo CD Redis component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Redis component are in a Ready state. Failed: At least one + of the Argo CD Redis component Pods had a failure. Unknown: The + state of the Argo CD Redis component could not be obtained.' + type: string + redisTLSChecksum: + description: RedisTLSChecksum contains the SHA256 checksum of the + latest known state of tls.crt and tls.key in the argocd-operator-redis-tls + secret. + type: string + repo: + description: 'Repo is a simple, high-level summary of where the Argo + CD Repo component is in its lifecycle. There are four possible repo + values: Pending: The Argo CD Repo component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Repo component are in a Ready state. Failed: At least one + of the Argo CD Repo component Pods had a failure. Unknown: The + state of the Argo CD Repo component could not be obtained.' + type: string + repoTLSChecksum: + description: RepoTLSChecksum contains the SHA256 checksum of the latest + known state of tls.crt and tls.key in the argocd-repo-server-tls + secret. + type: string + server: + description: 'Server is a simple, high-level summary of where the + Argo CD server component is in its lifecycle. There are four possible + server values: Pending: The Argo CD server component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD server component are in a Ready state. Failed: At least + one of the Argo CD server component Pods had a failure. Unknown: + The state of the Argo CD server component could not be obtained.' + type: string + sso: + description: 'SSO is a simple, high-level summary of where the Argo + CD SSO(Dex/Keycloak) component is in its lifecycle. There are four + possible sso values: Pending: The Argo CD SSO component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD SSO component are in a Ready state. Failed: At least + one of the Argo CD SSO component Pods had a failure. Unknown: The + state of the Argo CD SSO component could not be obtained.' + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: description: ArgoCD is the Schema for the argocds API diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml new file mode 100644 index 000000000..52d866183 --- /dev/null +++ b/config/certmanager/certificate.yaml @@ -0,0 +1,25 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + dnsNames: + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc + - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml new file mode 100644 index 000000000..bebea5a59 --- /dev/null +++ b/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 000000000..90d7c313c --- /dev/null +++ b/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index b2c21ff3b..8a2a79f9a 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -16,7 +16,6451 @@ spec: singular: argocd scope: Namespaced versions: - - name: v1alpha1 + - deprecated: true + deprecationWarning: ArgoCD v1alpha1 is deprecated, please use v1beta1 instead. + name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCD is the Schema for the argocds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDSpec defines the desired state of ArgoCD + properties: + applicationInstanceLabelKey: + description: ApplicationInstanceLabelKey is the key name where Argo + CD injects the app name as a tracking label. + type: string + applicationSet: + description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet + controller should be installed. + properties: + env: + description: Env lets you specify environment for applicationSet + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: ExtraCommandArgs allows users to pass command line + arguments to ApplicationSet controller. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the Argo CD ApplicationSet image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for ApplicationSet. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD ApplicationSet image tag. + (optional) + type: string + webhookServer: + description: WebhookServerSpec defines the options for the ApplicationSet + Webhook Server component. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + use for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the + Route resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the + contents of the ca certificate of the final destination. When + using reencrypt termination this file should be + provided in order to have routers use it for health + checks on the secure connection. If this field is + not specified, the router may provide its own destination + CA and perform hostname validation using the short + service name (service.namespace.svc), which allows + infrastructure generated certificates to automatically + verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to + a route. While each router may make its own decisions + on which ports to expose, this is normally port + 80. \n * Allow - traffic is sent to the server on + the insecure port (default) * Disable - no traffic + is allowed on the insecure port. * Redirect - clients + are redirected to the secure port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + type: object + type: object + banner: + description: Banner defines an additional banner to be displayed in + Argo CD UI + properties: + content: + description: Content defines the banner message content to display + type: string + url: + description: URL defines an optional URL to be used as banner + message link + type: string + required: + - content + type: object + configManagementPlugins: + description: ConfigManagementPlugins is used to specify additional + config management plugins. + type: string + controller: + description: Controller defines the Application Controller options + for ArgoCD. + properties: + appSync: + description: "AppSync is used to control the sync frequency, by + default the ArgoCD controller polls Git every 3m. \n Set this + to a duration, e.g. 10m or 600s to control the synchronisation + frequency." + type: string + env: + description: Env lets you specify environment for application + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + logFormat: + description: LogFormat refers to the log format used by the Application + Controller component. Defaults to ArgoCDDefaultLogFormat if + not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level used by the Application + Controller component. Defaults to ArgoCDDefaultLogLevel if not + configured. Valid options are debug, info, error, and warn. + type: string + parallelismLimit: + description: ParallelismLimit defines the limit for parallel kubectl + operations + format: int32 + type: integer + processors: + description: Processors contains the options for the Application + Controller processors. + properties: + operation: + description: Operation is the number of application operation + processors. + format: int32 + type: integer + status: + description: Status is the number of application status processors. + format: int32 + type: integer + type: object + resources: + description: Resources defines the Compute Resources required + by the container for the Application Controller. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + sharding: + description: Sharding contains the options for the Application + Controller sharding configuration. + properties: + clustersPerShard: + description: ClustersPerShard defines the maximum number of + clusters managed by each argocd shard + format: int32 + minimum: 1 + type: integer + dynamicScalingEnabled: + description: DynamicScalingEnabled defines whether dynamic + scaling should be enabled for Application Controller component + type: boolean + enabled: + description: Enabled defines whether sharding should be enabled + on the Application Controller component. + type: boolean + maxShards: + description: MaxShards defines the maximum number of shards + at any given point + format: int32 + type: integer + minShards: + description: MinShards defines the minimum number of shards + at any given point + format: int32 + minimum: 1 + type: integer + replicas: + description: Replicas defines the number of replicas to run + in the Application controller shard. + format: int32 + type: integer + type: object + type: object + dex: + description: Deprecated field. Support dropped in v1beta1 version. + Dex defines the Dex server options for ArgoCD. + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must be a + member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + disableAdmin: + description: DisableAdmin will disable the admin user. + type: boolean + extraConfig: + additionalProperties: + type: string + description: "ExtraConfig can be used to add fields to Argo CD configmap + that are not supported by Argo CD CRD. \n Note: ExtraConfig takes + precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` + = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. + In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] + = true." + type: object + gaAnonymizeUsers: + description: GAAnonymizeUsers toggles user IDs being hashed before + sending to google analytics. + type: boolean + gaTrackingID: + description: GATrackingID is the google analytics tracking ID to use. + type: string + grafana: + description: Grafana defines the Grafana server options for ArgoCD. + properties: + enabled: + description: Enabled will toggle Grafana support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + image: + description: Image is the Grafana container image. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + resources: + description: Resources defines the Compute Resources required + by the container for Grafana. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Grafana Deployment. + format: int32 + type: integer + version: + description: Version is the Grafana container image tag. + type: string + required: + - enabled + type: object + ha: + description: HA options for High Availability support for the Redis + component. + properties: + enabled: + description: Enabled will toggle HA support globally for Argo + CD. + type: boolean + redisProxyImage: + description: RedisProxyImage is the Redis HAProxy container image. + type: string + redisProxyVersion: + description: RedisProxyVersion is the Redis HAProxy container + image tag. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for HA. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - enabled + type: object + helpChatText: + description: HelpChatText is the text for getting chat help, defaults + to "Chat now!" + type: string + helpChatURL: + description: HelpChatURL is the URL for getting chat help, this will + typically be your Slack channel for support. + type: string + image: + description: Image is the ArgoCD container image for all ArgoCD components. + type: string + import: + description: Import is the import/restore options for ArgoCD. + properties: + name: + description: Name of an ArgoCDExport from which to import data. + type: string + namespace: + description: Namespace for the ArgoCDExport, defaults to the same + namespace as the ArgoCD. + type: string + required: + - name + type: object + initialRepositories: + description: InitialRepositories to configure Argo CD with upon creation + of the cluster. + type: string + initialSSHKnownHosts: + description: InitialSSHKnownHosts defines the SSH known hosts data + upon creation of the cluster for connecting Git repositories via + SSH. + properties: + excludedefaulthosts: + description: ExcludeDefaultHosts describes whether you would like + to include the default list of SSH Known Hosts provided by ArgoCD. + type: boolean + keys: + description: Keys describes a custom set of SSH Known Hosts that + you would like to have included in your ArgoCD server. + type: string + type: object + kustomizeBuildOptions: + description: KustomizeBuildOptions is used to specify build options/parameters + to use with `kustomize build`. + type: string + kustomizeVersions: + description: KustomizeVersions is a listing of configured versions + of Kustomize to be made available within ArgoCD. + items: + description: KustomizeVersionSpec is used to specify information + about a kustomize version to be used within ArgoCD. + properties: + path: + description: Path is the path to a configured kustomize version + on the filesystem of your repo server. + type: string + version: + description: Version is a configured kustomize version in the + format of vX.Y.Z + type: string + type: object + type: array + monitoring: + description: Monitoring defines whether workload status monitoring + configuration for this instance. + properties: + enabled: + description: Enabled defines whether workload status monitoring + is enabled for this instance or not + type: boolean + required: + - enabled + type: object + nodePlacement: + description: NodePlacement defines NodeSelectors and Taints for Argo + CD workloads + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a field of PodSpec, it is a map of + key value pairs used for node selection + type: object + tolerations: + description: Tolerations allow the pods to schedule onto nodes + with matching taints + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + notifications: + description: Notifications defines whether the Argo CD Notifications + controller should be installed. + properties: + enabled: + description: Enabled defines whether argocd-notifications controller + should be deployed or not + type: boolean + env: + description: Env let you specify environment variables for Notifications + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Image is the Argo CD Notifications image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas to run for + notifications-controller + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Argo CD Notifications. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD Notifications image tag. (optional) + type: string + required: + - enabled + type: object + oidcConfig: + description: OIDCConfig is the OIDC configuration as an alternative + to dex. + type: string + prometheus: + description: Prometheus defines the Prometheus server options for + ArgoCD. + properties: + enabled: + description: Enabled will toggle Prometheus support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Prometheus StatefulSet. + format: int32 + type: integer + required: + - enabled + type: object + rbac: + description: RBAC defines the RBAC configuration for Argo CD. + properties: + defaultPolicy: + description: DefaultPolicy is the name of the default role which + Argo CD will falls back to, when authorizing API requests (optional). + If omitted or empty, users may be still be able to login, but + will see no apps, projects, etc... + type: string + policy: + description: 'Policy is CSV containing user-defined RBAC policies + and role definitions. Policy rules are in the form: p, subject, + resource, action, object, effect Role definitions and bindings + are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + type: string + policyMatcherMode: + description: PolicyMatcherMode configures the matchers function + mode for casbin. There are two options for this, 'glob' for + glob matcher or 'regex' for regex matcher. + type: string + scopes: + description: 'Scopes controls which OIDC scopes to examine during + rbac enforcement (in addition to `sub` scope). If omitted, defaults + to: ''[groups]''.' + type: string + type: object + redis: + description: Redis defines the Redis server options for ArgoCD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the redis server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + disableTLSVerification: + description: DisableTLSVerification defines whether redis server + API should be accessed using strict TLS validation + type: boolean + image: + description: Image is the Redis container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Redis container image tag. + type: string + type: object + repo: + description: Repo defines the repo server options for Argo CD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the repo server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + env: + description: Env lets you specify environment for repo server + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + execTimeout: + description: ExecTimeout specifies the timeout in seconds for + tool execution + type: integer + extraRepoCommandArgs: + description: Extra Command arguments allows users to pass command + line arguments to repo server workload. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraRepoCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the ArgoCD Repo Server container image. + type: string + initContainers: + description: InitContainers defines the list of initialization + containers for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + logFormat: + description: LogFormat describes the log format that should be + used by the Repo Server. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not + set. Valid options are debug, info, error, and warn. + type: string + mountsatoken: + description: MountSAToken describes whether you would like to + have the Repo server mount the service account token + type: boolean + replicas: + description: Replicas defines the number of replicas for argocd-repo-server. + Value should be greater than or equal to 0. Default is nil. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceaccount: + description: ServiceAccount defines the ServiceAccount user that + you would like the Repo server to use + type: string + sidecarContainers: + description: SidecarContainers defines the list of sidecar containers + for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + verifytls: + description: VerifyTLS defines whether repo server API should + be accessed using strict TLS validation + type: boolean + version: + description: Version is the ArgoCD Repo Server container image + tag. + type: string + volumeMounts: + description: VolumeMounts adds volumeMounts to the repo server + container + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes adds volumes to the repo server deployment + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force and set the ReadOnly + property in VolumeMounts to "true". If omitted, the + default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent disk resource + in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, Read Only, Read + Write.' + type: string + diskName: + description: The Name of the data disk in the blob storage + type: string + diskURI: + description: The URI the data disk in the blob storage + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + kind: + description: 'Expected values Shared: multiple blob + disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that contains Azure + Storage Account Name and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'Required: Monitors is a collection of + Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the mounted root, rather + than the full Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile is the path to key + ring for User, default is /etc/ceph/user.secret More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef is reference to the + authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'Optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to a secret object containing + parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the ConfigMap, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its keys + must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: Driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: Filesystem type to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: Specifies a read-only configuration for + the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage medium should back + this directory. The default is "" which means to use + the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'Total amount of local storage required + for this EmptyDir volume. The size limit is also applicable + for memory medium. The maximum usage on memory medium + EmptyDir would be the minimum value between the SizeLimit + specified here and the sum of memory limits of all + containers in a pod. The default is nil which means + that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "Ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'AccessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify + either: * An existing VolumeSnapshot object + (snapshot.storage.k8s.io/VolumeSnapshot) * + An existing PVC (PersistentVolumeClaim) If + the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. If the AnyVolumeDataSource + feature gate is enabled, this field will always + have the same contents as the DataSourceRef + field.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'Specifies the object from which + to populate the volume with data, if a non-empty + volume is desired. This may be any local object + from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this + field is specified, volume binding will only + succeed if the type of the specified object + matches some installed volume populator or + dynamic provisioner. This field will replace + the functionality of the DataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, both fields (DataSource and + DataSourceRef) will be set to the same value + automatically if one of them is empty and + the other is non-empty. There are two important + differences between DataSource and DataSourceRef: + * While DataSource only allows two specific + types of objects, DataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While DataSource ignores disallowed + values (dropping them), DataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. (Alpha) Using this field + requires the AnyVolumeDataSource feature gate + to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: A label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required + by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: VolumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: FC represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: Driver is the name of the driver to use + for this volume. + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". The default filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command options if any.' + type: object + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef is reference to the + secret object containing sensitive information to + pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the + plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored as metadata + -> name on the dataset for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD resource in GCE. + Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. Must not contain + or start with '..'. If '.' is supplied, the volume + directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator Name. If initiatorName + is specified with iscsiInterface simultaneously, new + iSCSI interface : will + be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iSCSI Interface Name that uses an iSCSI + transport. Defaults to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. The portal is + either an IP or ip_addr:port if the port is other + than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI target and initiator + authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. The Portal is either + an IP or ip_addr:port if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + pdID: + description: ID that identifies Photon Controller persistent + disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: FSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources secrets, configmaps, + and downward API + properties: + defaultMode: + description: Mode bits used to set permissions on created + files by default. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. Directories within the + path are not affected by this setting. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: information about the configMap data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + downwardAPI: + description: information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about the secret data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + type: object + serviceAccountToken: + description: information about the serviceAccountToken + data to project + properties: + audience: + description: Audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: Path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: Quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: Group to map volume access to Default is + no group + type: string + readOnly: + description: ReadOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: Tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: Volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph monitors. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. Default is rbd. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'The rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: The host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO Protection Domain + for the configured storage. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: Indicates whether the storage for a volume + should be ThickProvisioned or ThinProvisioned. Default + is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool associated with + the protection domain. + type: string + system: + description: The name of the storage system as configured + in ScaleIO. + type: string + volumeName: + description: The name of a volume already created in + the ScaleIO system that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start + with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret or its keys + must be defined + type: boolean + secretName: + description: 'Name of the secret in the pod''s namespace + to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + storagePolicyID: + description: Storage Policy Based Management (SPBM) + profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based Management (SPBM) + profile name. + type: string + volumePath: + description: Path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + repositoryCredentials: + description: RepositoryCredentials are the Git pull credentials to + configure Argo CD with upon creation of the cluster. + type: string + resourceActions: + description: ResourceActions customizes resource action behavior. + items: + description: Resource Customization for custom action + properties: + action: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceCustomizations: + description: 'ResourceCustomizations customizes resource behavior. + Keys are in the form: group/Kind. Please note that this is being + deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' + type: string + resourceExclusions: + description: ResourceExclusions is used to completely ignore entire + classes of resource group/kinds. + type: string + resourceHealthChecks: + description: ResourceHealthChecks customizes resource health check + behavior. + items: + description: Resource Customization for custom health check + properties: + check: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceIgnoreDifferences: + description: ResourceIgnoreDifferences customizes resource ignore + difference behavior. + properties: + all: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + resourceIdentifiers: + items: + description: Resource Customization fields for ignore difference + properties: + customization: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + group: + type: string + kind: + type: string + type: object + type: array + type: object + resourceInclusions: + description: ResourceInclusions is used to only include specific group/kinds + in the reconciliation process. + type: string + resourceTrackingMethod: + description: ResourceTrackingMethod defines how Argo CD should track + resources that it manages + type: string + server: + description: Server defines the options for the ArgoCD Server component. + properties: + autoscale: + description: Autoscale defines the autoscale options for the Argo + CD Server component. + properties: + enabled: + description: Enabled will toggle autoscaling support for the + Argo CD Server component. + type: boolean + hpa: + description: HPA defines the HorizontalPodAutoscaler options + for the Argo CD Server component. + properties: + maxReplicas: + description: upper limit for the number of pods that can + be set by the autoscaler; cannot be smaller than MinReplicas. + format: int32 + type: integer + minReplicas: + description: minReplicas is the lower limit for the number + of replicas to which the autoscaler can scale down. It + defaults to 1 pod. minReplicas is allowed to be 0 if + the alpha feature gate HPAScaleToZero is enabled and + at least one Object or External metric is configured. Scaling + is active as long as at least one metric value is available. + format: int32 + type: integer + scaleTargetRef: + description: reference to scaled resource; horizontal + pod autoscaler will learn the current resource consumption + and will set the desired number of pods by using its + Scale subresource. + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + type: string + name: + description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + required: + - kind + - name + type: object + targetCPUUtilizationPercentage: + description: target average CPU utilization (represented + as a percentage of requested CPU) over all the pods; + if not specified the default autoscaling policy will + be used. + format: int32 + type: integer + required: + - maxReplicas + - scaleTargetRef + type: object + required: + - enabled + type: object + env: + description: Env lets you specify environment for API server pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: Extra Command arguments that would append to the + Argo CD server command. ExtraCommandArgs will not be added, + if one of these commands is already part of the server command + with same or different value. + items: + type: string + type: array + grpc: + description: GRPC defines the state for the Argo CD Server GRPC + options. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for the Argo + CD Server GRPC Ingress. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + type: object + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + insecure: + description: Insecure toggles the insecure flag. + type: boolean + logFormat: + description: LogFormat refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if + not set. Valid options are debug, info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas for argocd-server. + Default is nil. Value should be greater than or equal to 0. + Value will be ignored if Autoscaler is enabled. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for the Argo CD server component. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + service: + description: Service defines the options for the Service backing + the ArgoCD Server component. + properties: + type: + description: Type is the ServiceType to use for the Service + resource. + type: string + required: + - type + type: object + type: object + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sso: + description: SSO defines the Single Sign-on configuration for Argo + CD + properties: + dex: + description: Dex contains the configuration for Argo CD dex authentication + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must + be a member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + image: + description: Deprecated field. Support dropped in v1beta1 version. + Image is the SSO container image. + type: string + keycloak: + description: Keycloak contains the configuration for Argo CD keycloak + authentication + properties: + image: + description: Image is the Keycloak container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Keycloak. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + rootCA: + description: Custom root CA certificate for communicating + with the Keycloak OIDC provider + type: string + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the Keycloak container image tag. + type: string + type: object + provider: + description: Provider installs and configures the given SSO Provider + with Argo CD. + type: string + resources: + description: Deprecated field. Support dropped in v1beta1 version. + Resources defines the Compute Resources required by the container + for SSO. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + verifyTLS: + description: Deprecated field. Support dropped in v1beta1 version. + VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Deprecated field. Support dropped in v1beta1 version. + Version is the SSO container image tag. + type: string + type: object + statusBadgeEnabled: + description: StatusBadgeEnabled toggles application status badge feature. + type: boolean + tls: + description: TLS defines the TLS options for ArgoCD. + properties: + ca: + description: CA defines the CA options. + properties: + configMapName: + description: ConfigMapName is the name of the ConfigMap containing + the CA Certificate. + type: string + secretName: + description: SecretName is the name of the Secret containing + the CA Certificate and Key. + type: string + type: object + initialCerts: + additionalProperties: + type: string + description: InitialCerts defines custom TLS certificates upon + creation of the cluster for connecting Git repositories via + HTTPS. + type: object + type: object + usersAnonymousEnabled: + description: UsersAnonymousEnabled toggles anonymous user access. + The anonymous users get default role permissions specified argocd-rbac-cm. + type: boolean + version: + description: Version is the tag to use with the ArgoCD container image + for all ArgoCD components. + type: string + type: object + status: + description: ArgoCDStatus defines the observed state of ArgoCD + properties: + applicationController: + description: 'ApplicationController is a simple, high-level summary + of where the Argo CD application controller component is in its + lifecycle. There are four possible ApplicationController values: + Pending: The Argo CD application controller component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD application controller component are in a Ready state. Failed: + At least one of the Argo CD application controller component Pods + had a failure. Unknown: The state of the Argo CD application controller + component could not be obtained.' + type: string + applicationSetController: + description: 'ApplicationSetController is a simple, high-level summary + of where the Argo CD applicationSet controller component is in its + lifecycle. There are four possible ApplicationSetController values: + Pending: The Argo CD applicationSet controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD applicationSet controller component are in a Ready + state. Failed: At least one of the Argo CD applicationSet controller + component Pods had a failure. Unknown: The state of the Argo CD + applicationSet controller component could not be obtained.' + type: string + host: + description: Host is the hostname of the Ingress. + type: string + notificationsController: + description: 'NotificationsController is a simple, high-level summary + of where the Argo CD notifications controller component is in its + lifecycle. There are four possible NotificationsController values: + Pending: The Argo CD notifications controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD notifications controller component are in a Ready + state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD + notifications controller component could not be obtained.' + type: string + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCD + is in its lifecycle. There are four possible phase values: Pending: + The ArgoCD has been accepted by the Kubernetes system, but one or + more of the required resources have not been created. Available: + All of the resources for the ArgoCD are ready. Failed: At least + one resource has experienced a failure. Unknown: The state of the + ArgoCD phase could not be obtained.' + type: string + redis: + description: 'Redis is a simple, high-level summary of where the Argo + CD Redis component is in its lifecycle. There are four possible + redis values: Pending: The Argo CD Redis component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Redis component are in a Ready state. Failed: At least one + of the Argo CD Redis component Pods had a failure. Unknown: The + state of the Argo CD Redis component could not be obtained.' + type: string + redisTLSChecksum: + description: RedisTLSChecksum contains the SHA256 checksum of the + latest known state of tls.crt and tls.key in the argocd-operator-redis-tls + secret. + type: string + repo: + description: 'Repo is a simple, high-level summary of where the Argo + CD Repo component is in its lifecycle. There are four possible repo + values: Pending: The Argo CD Repo component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Repo component are in a Ready state. Failed: At least one + of the Argo CD Repo component Pods had a failure. Unknown: The + state of the Argo CD Repo component could not be obtained.' + type: string + repoTLSChecksum: + description: RepoTLSChecksum contains the SHA256 checksum of the latest + known state of tls.crt and tls.key in the argocd-repo-server-tls + secret. + type: string + server: + description: 'Server is a simple, high-level summary of where the + Argo CD server component is in its lifecycle. There are four possible + server values: Pending: The Argo CD server component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD server component are in a Ready state. Failed: At least + one of the Argo CD server component Pods had a failure. Unknown: + The state of the Argo CD server component could not be obtained.' + type: string + sso: + description: 'SSO is a simple, high-level summary of where the Argo + CD SSO(Dex/Keycloak) component is in its lifecycle. There are four + possible sso values: Pending: The Argo CD SSO component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD SSO component are in a Ready state. Failed: At least + one of the Argo CD SSO component Pods had a failure. Unknown: The + state of the Argo CD SSO component could not be obtained.' + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: description: ArgoCD is the Schema for the argocds API diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 92f59ee01..affcaaf1f 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -13,13 +13,13 @@ resources: patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_argocds.yaml +- patches/webhook_in_argocds.yaml #- patches/webhook_in_argocdexports.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_argocds.yaml +- patches/cainjection_in_argocds.yaml #- patches/cainjection_in_argocdexports.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch diff --git a/config/crd/patches/cainjection_in_argocds.yaml b/config/crd/patches/cainjection_in_argocds.yaml index 82ce1cd09..9e862ad0f 100644 --- a/config/crd/patches/cainjection_in_argocds.yaml +++ b/config/crd/patches/cainjection_in_argocds.yaml @@ -1,7 +1,5 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD +# The following patch adds a directive for certmanager/service ca to inject CA into the CRD apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) name: argocds.argoproj.io diff --git a/config/crd/patches/webhook_in_argocds.yaml b/config/crd/patches/webhook_in_argocds.yaml index 555a89829..b5e743d11 100644 --- a/config/crd/patches/webhook_in_argocds.yaml +++ b/config/crd/patches/webhook_in_argocds.yaml @@ -13,4 +13,5 @@ spec: name: webhook-service path: /convert conversionReviewVersions: - - v1 + - v1alpha1 + - v1beta1 diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 05ab0e7e5..89a72e9b2 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -18,7 +18,7 @@ bases: - ../manager # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- ../webhook +- ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. #- ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. @@ -36,7 +36,7 @@ patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- manager_webhook_patch.yaml +- manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml new file mode 100644 index 000000000..738de350b --- /dev/null +++ b/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml new file mode 100644 index 000000000..02ab515d4 --- /dev/null +++ b/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manifests/bases/argocd-operator.clusterserviceversion.yaml b/config/manifests/bases/argocd-operator.clusterserviceversion.yaml index 07a5f0056..03573a220 100644 --- a/config/manifests/bases/argocd-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/argocd-operator.clusterserviceversion.yaml @@ -114,6 +114,583 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text version: v1alpha1 + - description: ArgoCD is the Schema for the argocds API + displayName: Argo CD + kind: ArgoCD + name: argocds.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1beta1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: ApplicationInstanceLabelKey is the key name where Argo CD injects + the app name as a tracking label. + displayName: Application Instance Label Key' + path: applicationInstanceLabelKey + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: applicationSet.webhookServer.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: applicationSet.webhookServer.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: applicationSet.webhookServer.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ConfigManagementPlugins is used to specify additional config + management plugins. + displayName: Config Management Plugins' + path: configManagementPlugins + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Operation is the number of application operation processors. + displayName: Operation Processor Count' + path: controller.processors.operation + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Status is the number of application status processors. + displayName: Status Processor Count' + path: controller.processors.status + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resources defines the Compute Resources required by the container + for the Application Controller. + displayName: Resource Requirements' + path: controller.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: GAAnonymizeUsers toggles user IDs being hashed before sending + to google analytics. + displayName: Google Analytics Anonymize Users' + path: gaAnonymizeUsers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: GATrackingID is the google analytics tracking ID to use. + displayName: Google Analytics Tracking ID' + path: gaTrackingID + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Grafana support globally for ArgoCD. + displayName: Enabled + path: grafana.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: grafana.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Grafana container image. + displayName: Image + path: grafana.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: grafana.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Grafana. + displayName: Resource Requirements' + path: grafana.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: grafana.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Grafana Deployment. + displayName: Size + path: grafana.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Version is the Grafana container image tag. + displayName: Version + path: grafana.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle HA support globally for Argo CD. + displayName: Enabled + path: ha.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: HelpChatText is the text for getting chat help, defaults to "Chat + now!" + displayName: Help Chat Text' + path: helpChatText + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: HelpChatURL is the URL for getting chat help, this will typically + be your Slack channel for support. + displayName: Help Chat URL' + path: helpChatURL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Image is the ArgoCD container image for all ArgoCD components. + displayName: Image + path: image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of an ArgoCDExport from which to import data. + displayName: Name + path: import.name + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: Namespace for the ArgoCDExport, defaults to the same namespace + as the ArgoCD. + displayName: Namespace + path: import.namespace + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: InitialRepositories to configure Argo CD with upon creation of + the cluster. + displayName: Initial Repositories' + path: initialRepositories + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: KustomizeVersions is a listing of configured versions of Kustomize + to be made available within ArgoCD. + displayName: Kustomize Build Options' + path: kustomizeVersions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: OIDCConfig is the OIDC configuration as an alternative to dex. + displayName: OIDC Config' + path: oidcConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Prometheus support globally for ArgoCD. + displayName: Enabled + path: prometheus.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: prometheus.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: prometheus.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: prometheus.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Prometheus StatefulSet. + displayName: Size + path: prometheus.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: DefaultPolicy is the name of the default role which Argo CD will + falls back to, when authorizing API requests (optional). If omitted or empty, + users may be still be able to login, but will see no apps, projects, etc... + displayName: Default Policy' + path: rbac.defaultPolicy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Policy is CSV containing user-defined RBAC policies and role + definitions. Policy rules are in the form: p, subject, resource, action, + object, effect Role definitions and bindings are in the form: g, subject, + inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + displayName: Policy + path: rbac.policy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Scopes controls which OIDC scopes to examine during rbac enforcement + (in addition to `sub` scope). If omitted, defaults to: ''[groups]''.' + displayName: Scopes + path: rbac.scopes + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Redis container image. + displayName: Image + path: redis.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: redis.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Redis container image tag. + displayName: Version + path: redis.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: repo.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: ResourceActions customizes resource action behavior. + displayName: Resource Action Customizations' + path: resourceActions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'ResourceCustomizations customizes resource behavior. Keys are + in the form: group/Kind. Please note that this is being deprecated in favor + of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + displayName: Resource Customizations' + path: resourceCustomizations + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceExclusions is used to completely ignore entire classes + of resource group/kinds. + displayName: Resource Exclusions' + path: resourceExclusions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceHealthChecks customizes resource health check behavior. + displayName: Resource Health Check Customizations' + path: resourceHealthChecks + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceIgnoreDifferences customizes resource ignore difference + behavior. + displayName: Resource Ignore Difference Customizations' + path: resourceIgnoreDifferences + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceTrackingMethod defines how Argo CD should track resources + that it manages + displayName: Resource Tracking Method' + path: resourceTrackingMethod + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle autoscaling support for the Argo CD Server + component. + displayName: Autoscale Enabled' + path: server.autoscale.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: GRPC Host + path: server.grpc.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Ingress defines the desired state for the Argo CD Server GRPC + Ingress. + displayName: GRPC Ingress Enabled' + path: server.grpc.ingress + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.grpc.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: server.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Insecure toggles the insecure flag. + displayName: Insecure + path: server.insecure + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for the Argo CD server component. + displayName: Resource Requirements' + path: server.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: server.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Type is the ServiceType to use for the Service resource. + displayName: Service Type' + path: server.service.type + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Config is the dex connector configuration. + displayName: Configuration + path: sso.dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: sso.dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: sso.dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: sso.dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: sso.dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: StatusBadgeEnabled toggles application status badge feature. + displayName: Status Badge Enabled' + path: statusBadgeEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: UsersAnonymousEnabled toggles anonymous user access. The anonymous + users get default role permissions specified argocd-rbac-cm. + displayName: Anonymous Users Enabled' + path: usersAnonymousEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Version is the tag to use with the ArgoCD container image for + all ArgoCD components. + displayName: Version + path: version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + statusDescriptors: + - description: 'ApplicationController is a simple, high-level summary of where + the Argo CD application controller component is in its lifecycle. There + are four possible ApplicationController values: Pending: The Argo CD application + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD application controller component are in + a Ready state. Failed: At least one of the Argo CD application controller + component Pods had a failure. Unknown: The state of the Argo CD application + controller component could not be obtained.' + displayName: ApplicationController + path: applicationController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'ApplicationSetController is a simple, high-level summary of + where the Argo CD applicationSet controller component is in its lifecycle. + There are four possible ApplicationSetController values: Pending: The Argo + CD applicationSet controller component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD applicationSet controller + component are in a Ready state. Failed: At least one of the Argo CD applicationSet + controller component Pods had a failure. Unknown: The state of the Argo + CD applicationSet controller component could not be obtained.' + displayName: ApplicationSetController + path: applicationSetController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'NotificationsController is a simple, high-level summary of where + the Argo CD notifications controller component is in its lifecycle. There + are four possible NotificationsController values: Pending: The Argo CD notifications + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD notifications controller component are + in a Ready state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD notifications + controller component could not be obtained.' + displayName: NotificationsController + path: notificationsController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Phase is a simple, high-level summary of where the ArgoCD is + in its lifecycle. There are four possible phase values: Pending: The ArgoCD + has been accepted by the Kubernetes system, but one or more of the required + resources have not been created. Available: All of the resources for the + ArgoCD are ready. Failed: At least one resource has experienced a failure. + Unknown: The state of the ArgoCD phase could not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Redis is a simple, high-level summary of where the Argo CD Redis + component is in its lifecycle. There are four possible redis values: Pending: + The Argo CD Redis component has been accepted by the Kubernetes system, + but one or more of the required resources have not been created. Running: + All of the required Pods for the Argo CD Redis component are in a Ready + state. Failed: At least one of the Argo CD Redis component Pods had a failure. + Unknown: The state of the Argo CD Redis component could not be obtained.' + displayName: Redis + path: redis + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Repo is a simple, high-level summary of where the Argo CD Repo + component is in its lifecycle. There are four possible repo values: Pending: + The Argo CD Repo component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Repo component are in a Ready state. + Failed: At least one of the Argo CD Repo component Pods had a failure. + Unknown: The state of the Argo CD Repo component could not be obtained.' + displayName: Repo + path: repo + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Server is a simple, high-level summary of where the Argo CD + server component is in its lifecycle. There are four possible server values: + Pending: The Argo CD server component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD server component are in + a Ready state. Failed: At least one of the Argo CD server component Pods + had a failure. Unknown: The state of the Argo CD server component could + not be obtained.' + displayName: Server + path: server + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) + component is in its lifecycle. There are four possible sso values: Pending: + The Argo CD SSO component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD SSO component are in a Ready state. + Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: + The state of the Argo CD SSO component could not be obtained.' + displayName: SSO + path: sso + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1beta1 - description: ArgoCD is the Schema for the argocds API displayName: Argo CD kind: ArgoCD @@ -223,6 +800,38 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Config is the dex connector configuration. + displayName: Configuration + path: dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text - description: GAAnonymizeUsers toggles user IDs being hashed before sending to google analytics. displayName: Google Analytics Anonymize Users' @@ -701,9 +1310,9 @@ spec: deployments: null strategy: "" installModes: - - supported: true + - supported: false type: OwnNamespace - - supported: true + - supported: false type: SingleNamespace - supported: false type: MultiNamespace diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index d61273ccc..bc680e8c0 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -9,22 +9,28 @@ resources: # [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. # Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. # These patches remove the unnecessary "cert" volume and its manager container volumeMount. -#patchesJson6902: -#- target: -# group: apps -# version: v1 -# kind: Deployment -# name: controller-manager -# namespace: system -# patch: |- -# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/containers/1/volumeMounts/0 -# # Remove the "cert" volume, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing volumes in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/volumes/0 +patchesJson6902: +- target: + group: apps + version: v1 + kind: Deployment + name: controller-manager + namespace: system + patch: |- + # Add ENABLE_CONVERSION_WEBHOOK env to enable conversion webhook + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: "ENABLE_CONVERSION_WEBHOOK" + value: "true" + # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. + # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. + - op: remove + path: /spec/template/spec/containers/0/volumeMounts/0 + # Remove the "cert" volume, since OLM will create and mount a set of certs. + # Update the indices in this path if adding or removing volumes in the manager's Deployment. + - op: remove + path: /spec/template/spec/volumes/0 patches: - target: diff --git a/config/samples/argoproj.io_v1beta1_argocd.yaml b/config/samples/argoproj.io_v1beta1_argocd.yaml new file mode 100644 index 000000000..cc02629c4 --- /dev/null +++ b/config/samples/argoproj.io_v1beta1_argocd.yaml @@ -0,0 +1,58 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-sample +spec: + server: + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 125m + memory: 128Mi + route: + enabled: true + repo: + resources: + limits: + cpu: 1000m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + ha: + enabled: false + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 250m + memory: 128Mi + redis: + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 250m + memory: 128Mi + sso: + provider: dex + dex: + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 250m + memory: 128Mi + controller: + resources: + limits: + cpu: 2000m + memory: 2048Mi + requests: + cpu: 250m + memory: 1024Mi diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 17456cb2a..d45f29bec 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -5,4 +5,5 @@ resources: - argoproj.io_v1alpha1_application.yaml - argoproj.io_v1alpha1_applicationset.yaml - argoproj.io_v1alpha1_appproject.yaml +- argoproj.io_v1beta1_argocd.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml new file mode 100644 index 000000000..13b9c632a --- /dev/null +++ b/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +#- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml new file mode 100644 index 000000000..25e21e3c9 --- /dev/null +++ b/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true + +varReference: +- path: metadata/annotations diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml new file mode 100644 index 000000000..4028ce206 --- /dev/null +++ b/config/webhook/service.yaml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: argocd-operator diff --git a/controllers/argocd/role_test.go b/controllers/argocd/role_test.go index cf68dbe68..0129048f6 100644 --- a/controllers/argocd/role_test.go +++ b/controllers/argocd/role_test.go @@ -25,7 +25,7 @@ func TestReconcileArgoCD_reconcileRole(t *testing.T) { assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "newNamespaceTest", a.Namespace)) - workloadIdentifier := common.ArgoCDApplicationControllerComponent + workloadIdentifier := common.ArgoCDApplicationControllerComponent expectedRules := policyRuleForApplicationController() _, err := r.reconcileRole(workloadIdentifier, expectedRules, a) assert.NoError(t, err) @@ -231,7 +231,7 @@ func TestReconcileRoles_ManagedTerminatingNamespace(t *testing.T) { // Create a managed namespace assert.NoError(t, createNamespace(r, "managedNS", a.Namespace)) - workloadIdentifier := common.ArgoCDApplicationControllerComponent + workloadIdentifier := common.ArgoCDApplicationControllerComponent expectedRules := policyRuleForApplicationController() _, err := r.reconcileRole(workloadIdentifier, expectedRules, a) assert.NoError(t, err) diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-webhook-service_v1_service.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-webhook-service_v1_service.yaml new file mode 100644 index 000000000..f5dda7bc9 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator-webhook-service_v1_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + name: argocd-operator-webhook-service +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: argocd-operator +status: + loadBalancer: {} diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml index f21e476df..a34457ca3 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml @@ -125,6 +125,94 @@ metadata: "spec": { "argocd": "argocd-sample" } + }, + { + "apiVersion": "argoproj.io/v1beta1", + "kind": "ArgoCD", + "metadata": { + "name": "argocd-sample" + }, + "spec": { + "controller": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "2048Mi" + }, + "requests": { + "cpu": "250m", + "memory": "1024Mi" + } + } + }, + "ha": { + "enabled": false, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "redis": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "repo": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "512Mi" + }, + "requests": { + "cpu": "250m", + "memory": "256Mi" + } + } + }, + "server": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "125m", + "memory": "128Mi" + } + }, + "route": { + "enabled": true + } + }, + "sso": { + "dex": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "provider": "dex" + } + } } ] capabilities: Deep Insights @@ -216,29 +304,638 @@ spec: path: argocd x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - - description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. - displayName: Schedule - path: schedule + - description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + displayName: Schedule + path: schedule + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Storage defines the storage configuration options. + displayName: Storage + path: storage + statusDescriptors: + - description: 'Phase is a simple, high-level summary of where the ArgoCDExport + is in its lifecycle. There are five possible phase values: Pending: The + ArgoCDExport has been accepted by the Kubernetes system, but one or more + of the required resources have not been created. Running: All of the containers + for the ArgoCDExport are still running, or in the process of starting or + restarting. Succeeded: All containers for the ArgoCDExport have terminated + in success, and will not be restarted. Failed: At least one container has + terminated in failure, either exited with non-zero status or was terminated + by the system. Unknown: For some reason the state of the ArgoCDExport could + not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1alpha1 + - description: ArgoCD is the Schema for the argocds API + displayName: Argo CD + kind: ArgoCD + name: argocds.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1alpha1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: ApplicationInstanceLabelKey is the key name where Argo CD injects + the app name as a tracking label. + displayName: Application Instance Label Key' + path: applicationInstanceLabelKey + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: applicationSet.webhookServer.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: applicationSet.webhookServer.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: applicationSet.webhookServer.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ConfigManagementPlugins is used to specify additional config + management plugins. + displayName: Config Management Plugins' + path: configManagementPlugins + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Operation is the number of application operation processors. + displayName: Operation Processor Count' + path: controller.processors.operation + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Status is the number of application status processors. + displayName: Status Processor Count' + path: controller.processors.status + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resources defines the Compute Resources required by the container + for the Application Controller. + displayName: Resource Requirements' + path: controller.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Config is the dex connector configuration. + displayName: Configuration + path: dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: GAAnonymizeUsers toggles user IDs being hashed before sending + to google analytics. + displayName: Google Analytics Anonymize Users' + path: gaAnonymizeUsers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: GATrackingID is the google analytics tracking ID to use. + displayName: Google Analytics Tracking ID' + path: gaTrackingID + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Grafana support globally for ArgoCD. + displayName: Enabled + path: grafana.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: grafana.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Grafana container image. + displayName: Image + path: grafana.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: grafana.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Grafana. + displayName: Resource Requirements' + path: grafana.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: grafana.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Grafana Deployment. + displayName: Size + path: grafana.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Version is the Grafana container image tag. + displayName: Version + path: grafana.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle HA support globally for Argo CD. + displayName: Enabled + path: ha.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: HelpChatText is the text for getting chat help, defaults to "Chat + now!" + displayName: Help Chat Text' + path: helpChatText + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: HelpChatURL is the URL for getting chat help, this will typically + be your Slack channel for support. + displayName: Help Chat URL' + path: helpChatURL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Image is the ArgoCD container image for all ArgoCD components. + displayName: Image + path: image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of an ArgoCDExport from which to import data. + displayName: Name + path: import.name + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: Namespace for the ArgoCDExport, defaults to the same namespace + as the ArgoCD. + displayName: Namespace + path: import.namespace + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: InitialRepositories to configure Argo CD with upon creation of + the cluster. + displayName: Initial Repositories' + path: initialRepositories + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: KustomizeVersions is a listing of configured versions of Kustomize + to be made available within ArgoCD. + displayName: Kustomize Build Options' + path: kustomizeVersions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: OIDCConfig is the OIDC configuration as an alternative to dex. + displayName: OIDC Config' + path: oidcConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Prometheus support globally for ArgoCD. + displayName: Enabled + path: prometheus.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: prometheus.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: prometheus.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: prometheus.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Prometheus StatefulSet. + displayName: Size + path: prometheus.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: DefaultPolicy is the name of the default role which Argo CD will + falls back to, when authorizing API requests (optional). If omitted or empty, + users may be still be able to login, but will see no apps, projects, etc... + displayName: Default Policy' + path: rbac.defaultPolicy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Policy is CSV containing user-defined RBAC policies and role + definitions. Policy rules are in the form: p, subject, resource, action, + object, effect Role definitions and bindings are in the form: g, subject, + inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + displayName: Policy + path: rbac.policy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Scopes controls which OIDC scopes to examine during rbac enforcement + (in addition to `sub` scope). If omitted, defaults to: ''[groups]''.' + displayName: Scopes + path: rbac.scopes + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Redis container image. + displayName: Image + path: redis.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: redis.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Redis container image tag. + displayName: Version + path: redis.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: repo.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: ResourceActions customizes resource action behavior. + displayName: Resource Action Customizations' + path: resourceActions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'ResourceCustomizations customizes resource behavior. Keys are + in the form: group/Kind. Please note that this is being deprecated in favor + of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + displayName: Resource Customizations' + path: resourceCustomizations + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceExclusions is used to completely ignore entire classes + of resource group/kinds. + displayName: Resource Exclusions' + path: resourceExclusions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceHealthChecks customizes resource health check behavior. + displayName: Resource Health Check Customizations' + path: resourceHealthChecks x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - - description: Storage defines the storage configuration options. - displayName: Storage - path: storage + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceIgnoreDifferences customizes resource ignore difference + behavior. + displayName: Resource Ignore Difference Customizations' + path: resourceIgnoreDifferences + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceTrackingMethod defines how Argo CD should track resources + that it manages + displayName: Resource Tracking Method' + path: resourceTrackingMethod + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle autoscaling support for the Argo CD Server + component. + displayName: Autoscale Enabled' + path: server.autoscale.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: GRPC Host + path: server.grpc.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Ingress defines the desired state for the Argo CD Server GRPC + Ingress. + displayName: GRPC Ingress Enabled' + path: server.grpc.ingress + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.grpc.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: server.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Insecure toggles the insecure flag. + displayName: Insecure + path: server.insecure + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for the Argo CD server component. + displayName: Resource Requirements' + path: server.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: server.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Type is the ServiceType to use for the Service resource. + displayName: Service Type' + path: server.service.type + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Config is the dex connector configuration. + displayName: Configuration + path: sso.dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: sso.dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: sso.dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: sso.dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: sso.dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: StatusBadgeEnabled toggles application status badge feature. + displayName: Status Badge Enabled' + path: statusBadgeEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: UsersAnonymousEnabled toggles anonymous user access. The anonymous + users get default role permissions specified argocd-rbac-cm. + displayName: Anonymous Users Enabled' + path: usersAnonymousEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Version is the tag to use with the ArgoCD container image for + all ArgoCD components. + displayName: Version + path: version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text statusDescriptors: - - description: 'Phase is a simple, high-level summary of where the ArgoCDExport - is in its lifecycle. There are five possible phase values: Pending: The - ArgoCDExport has been accepted by the Kubernetes system, but one or more - of the required resources have not been created. Running: All of the containers - for the ArgoCDExport are still running, or in the process of starting or - restarting. Succeeded: All containers for the ArgoCDExport have terminated - in success, and will not be restarted. Failed: At least one container has - terminated in failure, either exited with non-zero status or was terminated - by the system. Unknown: For some reason the state of the ArgoCDExport could - not be obtained.' + - description: 'ApplicationController is a simple, high-level summary of where + the Argo CD application controller component is in its lifecycle. There + are four possible ApplicationController values: Pending: The Argo CD application + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD application controller component are in + a Ready state. Failed: At least one of the Argo CD application controller + component Pods had a failure. Unknown: The state of the Argo CD application + controller component could not be obtained.' + displayName: ApplicationController + path: applicationController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'ApplicationSetController is a simple, high-level summary of + where the Argo CD applicationSet controller component is in its lifecycle. + There are four possible ApplicationSetController values: Pending: The Argo + CD applicationSet controller component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD applicationSet controller + component are in a Ready state. Failed: At least one of the Argo CD applicationSet + controller component Pods had a failure. Unknown: The state of the Argo + CD applicationSet controller component could not be obtained.' + displayName: ApplicationSetController + path: applicationSetController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'NotificationsController is a simple, high-level summary of where + the Argo CD notifications controller component is in its lifecycle. There + are four possible NotificationsController values: Pending: The Argo CD notifications + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD notifications controller component are + in a Ready state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD notifications + controller component could not be obtained.' + displayName: NotificationsController + path: notificationsController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Phase is a simple, high-level summary of where the ArgoCD is + in its lifecycle. There are four possible phase values: Pending: The ArgoCD + has been accepted by the Kubernetes system, but one or more of the required + resources have not been created. Available: All of the resources for the + ArgoCD are ready. Failed: At least one resource has experienced a failure. + Unknown: The state of the ArgoCD phase could not be obtained.' displayName: Phase path: phase x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Redis is a simple, high-level summary of where the Argo CD Redis + component is in its lifecycle. There are four possible redis values: Pending: + The Argo CD Redis component has been accepted by the Kubernetes system, + but one or more of the required resources have not been created. Running: + All of the required Pods for the Argo CD Redis component are in a Ready + state. Failed: At least one of the Argo CD Redis component Pods had a failure. + Unknown: The state of the Argo CD Redis component could not be obtained.' + displayName: Redis + path: redis + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Repo is a simple, high-level summary of where the Argo CD Repo + component is in its lifecycle. There are four possible repo values: Pending: + The Argo CD Repo component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Repo component are in a Ready state. + Failed: At least one of the Argo CD Repo component Pods had a failure. + Unknown: The state of the Argo CD Repo component could not be obtained.' + displayName: Repo + path: repo + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Server is a simple, high-level summary of where the Argo CD + server component is in its lifecycle. There are four possible server values: + Pending: The Argo CD server component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD server component are in + a Ready state. Failed: At least one of the Argo CD server component Pods + had a failure. Unknown: The state of the Argo CD server component could + not be obtained.' + displayName: Server + path: server + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) + component is in its lifecycle. There are four possible sso values: Pending: + The Argo CD SSO component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD SSO component are in a Ready state. + Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: + The state of the Argo CD SSO component could not be obtained.' + displayName: SSO + path: sso + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text version: v1alpha1 - description: ArgoCD is the Schema for the argocds API displayName: Argo CD @@ -247,7 +944,7 @@ spec: resources: - kind: ArgoCD name: "" - version: v1alpha1 + version: v1beta1 - kind: ArgoCDExport name: "" version: v1alpha1 @@ -816,7 +1513,7 @@ spec: path: sso x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - version: v1alpha1 + version: v1beta1 description: | ## Overview @@ -1050,6 +1747,8 @@ spec: valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: ENABLE_CONVERSION_WEBHOOK + value: "true" image: quay.io/argoprojlabs/argocd-operator:v0.8.0 livenessProbe: httpGet: @@ -1058,6 +1757,10 @@ spec: initialDelaySeconds: 15 periodSeconds: 20 name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP readinessProbe: httpGet: path: /readyz @@ -1112,9 +1815,9 @@ spec: serviceAccountName: argocd-operator-controller-manager strategy: deployment installModes: - - supported: true + - supported: false type: OwnNamespace - - supported: true + - supported: false type: SingleNamespace - supported: false type: MultiNamespace @@ -1138,3 +1841,16 @@ spec: name: Argo CD Community replaces: argocd-operator.v0.7.0 version: 0.8.0 + webhookdefinitions: + - admissionReviewVersions: + - v1alpha1 + - v1beta1 + containerPort: 443 + conversionCRDs: + - argocds.argoproj.io + deploymentName: argocd-operator-controller-manager + generateName: cargocds.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index 87d7c51d6..eb6530c06 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -6,6 +6,17 @@ metadata: creationTimestamp: null name: argocds.argoproj.io spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: argocd-operator-webhook-service + namespace: argocd-operator-system + path: /convert + conversionReviewVersions: + - v1alpha1 + - v1beta1 group: argoproj.io names: kind: ArgoCD @@ -14,7 +25,6451 @@ spec: singular: argocd scope: Namespaced versions: - - name: v1alpha1 + - deprecated: true + deprecationWarning: ArgoCD v1alpha1 is deprecated, please use v1beta1 instead. + name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCD is the Schema for the argocds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDSpec defines the desired state of ArgoCD + properties: + applicationInstanceLabelKey: + description: ApplicationInstanceLabelKey is the key name where Argo + CD injects the app name as a tracking label. + type: string + applicationSet: + description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet + controller should be installed. + properties: + env: + description: Env lets you specify environment for applicationSet + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: ExtraCommandArgs allows users to pass command line + arguments to ApplicationSet controller. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the Argo CD ApplicationSet image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for ApplicationSet. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD ApplicationSet image tag. + (optional) + type: string + webhookServer: + description: WebhookServerSpec defines the options for the ApplicationSet + Webhook Server component. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + use for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the + Route resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the + contents of the ca certificate of the final destination. When + using reencrypt termination this file should be + provided in order to have routers use it for health + checks on the secure connection. If this field is + not specified, the router may provide its own destination + CA and perform hostname validation using the short + service name (service.namespace.svc), which allows + infrastructure generated certificates to automatically + verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to + a route. While each router may make its own decisions + on which ports to expose, this is normally port + 80. \n * Allow - traffic is sent to the server on + the insecure port (default) * Disable - no traffic + is allowed on the insecure port. * Redirect - clients + are redirected to the secure port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + type: object + type: object + banner: + description: Banner defines an additional banner to be displayed in + Argo CD UI + properties: + content: + description: Content defines the banner message content to display + type: string + url: + description: URL defines an optional URL to be used as banner + message link + type: string + required: + - content + type: object + configManagementPlugins: + description: ConfigManagementPlugins is used to specify additional + config management plugins. + type: string + controller: + description: Controller defines the Application Controller options + for ArgoCD. + properties: + appSync: + description: "AppSync is used to control the sync frequency, by + default the ArgoCD controller polls Git every 3m. \n Set this + to a duration, e.g. 10m or 600s to control the synchronisation + frequency." + type: string + env: + description: Env lets you specify environment for application + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + logFormat: + description: LogFormat refers to the log format used by the Application + Controller component. Defaults to ArgoCDDefaultLogFormat if + not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level used by the Application + Controller component. Defaults to ArgoCDDefaultLogLevel if not + configured. Valid options are debug, info, error, and warn. + type: string + parallelismLimit: + description: ParallelismLimit defines the limit for parallel kubectl + operations + format: int32 + type: integer + processors: + description: Processors contains the options for the Application + Controller processors. + properties: + operation: + description: Operation is the number of application operation + processors. + format: int32 + type: integer + status: + description: Status is the number of application status processors. + format: int32 + type: integer + type: object + resources: + description: Resources defines the Compute Resources required + by the container for the Application Controller. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + sharding: + description: Sharding contains the options for the Application + Controller sharding configuration. + properties: + clustersPerShard: + description: ClustersPerShard defines the maximum number of + clusters managed by each argocd shard + format: int32 + minimum: 1 + type: integer + dynamicScalingEnabled: + description: DynamicScalingEnabled defines whether dynamic + scaling should be enabled for Application Controller component + type: boolean + enabled: + description: Enabled defines whether sharding should be enabled + on the Application Controller component. + type: boolean + maxShards: + description: MaxShards defines the maximum number of shards + at any given point + format: int32 + type: integer + minShards: + description: MinShards defines the minimum number of shards + at any given point + format: int32 + minimum: 1 + type: integer + replicas: + description: Replicas defines the number of replicas to run + in the Application controller shard. + format: int32 + type: integer + type: object + type: object + dex: + description: Deprecated field. Support dropped in v1beta1 version. + Dex defines the Dex server options for ArgoCD. + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must be a + member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + disableAdmin: + description: DisableAdmin will disable the admin user. + type: boolean + extraConfig: + additionalProperties: + type: string + description: "ExtraConfig can be used to add fields to Argo CD configmap + that are not supported by Argo CD CRD. \n Note: ExtraConfig takes + precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` + = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. + In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] + = true." + type: object + gaAnonymizeUsers: + description: GAAnonymizeUsers toggles user IDs being hashed before + sending to google analytics. + type: boolean + gaTrackingID: + description: GATrackingID is the google analytics tracking ID to use. + type: string + grafana: + description: Grafana defines the Grafana server options for ArgoCD. + properties: + enabled: + description: Enabled will toggle Grafana support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + image: + description: Image is the Grafana container image. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + resources: + description: Resources defines the Compute Resources required + by the container for Grafana. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Grafana Deployment. + format: int32 + type: integer + version: + description: Version is the Grafana container image tag. + type: string + required: + - enabled + type: object + ha: + description: HA options for High Availability support for the Redis + component. + properties: + enabled: + description: Enabled will toggle HA support globally for Argo + CD. + type: boolean + redisProxyImage: + description: RedisProxyImage is the Redis HAProxy container image. + type: string + redisProxyVersion: + description: RedisProxyVersion is the Redis HAProxy container + image tag. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for HA. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - enabled + type: object + helpChatText: + description: HelpChatText is the text for getting chat help, defaults + to "Chat now!" + type: string + helpChatURL: + description: HelpChatURL is the URL for getting chat help, this will + typically be your Slack channel for support. + type: string + image: + description: Image is the ArgoCD container image for all ArgoCD components. + type: string + import: + description: Import is the import/restore options for ArgoCD. + properties: + name: + description: Name of an ArgoCDExport from which to import data. + type: string + namespace: + description: Namespace for the ArgoCDExport, defaults to the same + namespace as the ArgoCD. + type: string + required: + - name + type: object + initialRepositories: + description: InitialRepositories to configure Argo CD with upon creation + of the cluster. + type: string + initialSSHKnownHosts: + description: InitialSSHKnownHosts defines the SSH known hosts data + upon creation of the cluster for connecting Git repositories via + SSH. + properties: + excludedefaulthosts: + description: ExcludeDefaultHosts describes whether you would like + to include the default list of SSH Known Hosts provided by ArgoCD. + type: boolean + keys: + description: Keys describes a custom set of SSH Known Hosts that + you would like to have included in your ArgoCD server. + type: string + type: object + kustomizeBuildOptions: + description: KustomizeBuildOptions is used to specify build options/parameters + to use with `kustomize build`. + type: string + kustomizeVersions: + description: KustomizeVersions is a listing of configured versions + of Kustomize to be made available within ArgoCD. + items: + description: KustomizeVersionSpec is used to specify information + about a kustomize version to be used within ArgoCD. + properties: + path: + description: Path is the path to a configured kustomize version + on the filesystem of your repo server. + type: string + version: + description: Version is a configured kustomize version in the + format of vX.Y.Z + type: string + type: object + type: array + monitoring: + description: Monitoring defines whether workload status monitoring + configuration for this instance. + properties: + enabled: + description: Enabled defines whether workload status monitoring + is enabled for this instance or not + type: boolean + required: + - enabled + type: object + nodePlacement: + description: NodePlacement defines NodeSelectors and Taints for Argo + CD workloads + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a field of PodSpec, it is a map of + key value pairs used for node selection + type: object + tolerations: + description: Tolerations allow the pods to schedule onto nodes + with matching taints + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + notifications: + description: Notifications defines whether the Argo CD Notifications + controller should be installed. + properties: + enabled: + description: Enabled defines whether argocd-notifications controller + should be deployed or not + type: boolean + env: + description: Env let you specify environment variables for Notifications + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Image is the Argo CD Notifications image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas to run for + notifications-controller + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Argo CD Notifications. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD Notifications image tag. (optional) + type: string + required: + - enabled + type: object + oidcConfig: + description: OIDCConfig is the OIDC configuration as an alternative + to dex. + type: string + prometheus: + description: Prometheus defines the Prometheus server options for + ArgoCD. + properties: + enabled: + description: Enabled will toggle Prometheus support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Prometheus StatefulSet. + format: int32 + type: integer + required: + - enabled + type: object + rbac: + description: RBAC defines the RBAC configuration for Argo CD. + properties: + defaultPolicy: + description: DefaultPolicy is the name of the default role which + Argo CD will falls back to, when authorizing API requests (optional). + If omitted or empty, users may be still be able to login, but + will see no apps, projects, etc... + type: string + policy: + description: 'Policy is CSV containing user-defined RBAC policies + and role definitions. Policy rules are in the form: p, subject, + resource, action, object, effect Role definitions and bindings + are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + type: string + policyMatcherMode: + description: PolicyMatcherMode configures the matchers function + mode for casbin. There are two options for this, 'glob' for + glob matcher or 'regex' for regex matcher. + type: string + scopes: + description: 'Scopes controls which OIDC scopes to examine during + rbac enforcement (in addition to `sub` scope). If omitted, defaults + to: ''[groups]''.' + type: string + type: object + redis: + description: Redis defines the Redis server options for ArgoCD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the redis server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + disableTLSVerification: + description: DisableTLSVerification defines whether redis server + API should be accessed using strict TLS validation + type: boolean + image: + description: Image is the Redis container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Redis container image tag. + type: string + type: object + repo: + description: Repo defines the repo server options for Argo CD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the repo server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + env: + description: Env lets you specify environment for repo server + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + execTimeout: + description: ExecTimeout specifies the timeout in seconds for + tool execution + type: integer + extraRepoCommandArgs: + description: Extra Command arguments allows users to pass command + line arguments to repo server workload. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraRepoCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the ArgoCD Repo Server container image. + type: string + initContainers: + description: InitContainers defines the list of initialization + containers for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + logFormat: + description: LogFormat describes the log format that should be + used by the Repo Server. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not + set. Valid options are debug, info, error, and warn. + type: string + mountsatoken: + description: MountSAToken describes whether you would like to + have the Repo server mount the service account token + type: boolean + replicas: + description: Replicas defines the number of replicas for argocd-repo-server. + Value should be greater than or equal to 0. Default is nil. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceaccount: + description: ServiceAccount defines the ServiceAccount user that + you would like the Repo server to use + type: string + sidecarContainers: + description: SidecarContainers defines the list of sidecar containers + for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker image''s + CMD is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The docker image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional information + about the network connections a container uses, but is + primarily informational. Not specifying a port here DOES + NOT prevent that port from being exposed. Any port which + is listening on the default "0.0.0.0" address inside a + container will be accessible from the network. Cannot + be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. This + field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature + flag will result in errors when validating the + Pod. All of a Pod's containers must have the same + effective HostProcess value (it is not allowed + to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. This is an alpha field and requires enabling + GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + verifytls: + description: VerifyTLS defines whether repo server API should + be accessed using strict TLS validation + type: boolean + version: + description: Version is the ArgoCD Repo Server container image + tag. + type: string + volumeMounts: + description: VolumeMounts adds volumeMounts to the repo server + container + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes adds volumes to the repo server deployment + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force and set the ReadOnly + property in VolumeMounts to "true". If omitted, the + default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent disk resource + in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, Read Only, Read + Write.' + type: string + diskName: + description: The Name of the data disk in the blob storage + type: string + diskURI: + description: The URI the data disk in the blob storage + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + kind: + description: 'Expected values Shared: multiple blob + disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: the name of secret that contains Azure + Storage Account Name and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'Required: Monitors is a collection of + Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the mounted root, rather + than the full Ceph tree, default is /' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile is the path to key + ring for User, default is /etc/ceph/user.secret More + info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef is reference to the + authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'Optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to a secret object containing + parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the ConfigMap, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its keys + must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: Driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: Filesystem type to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: Specifies a read-only configuration for + the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage medium should back + this directory. The default is "" which means to use + the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'Total amount of local storage required + for this EmptyDir volume. The size limit is also applicable + for memory medium. The maximum usage on memory medium + EmptyDir would be the minimum value between the SizeLimit + specified here and the sum of memory limits of all + containers in a pod. The default is nil which means + that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "Ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'AccessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'This field can be used to specify + either: * An existing VolumeSnapshot object + (snapshot.storage.k8s.io/VolumeSnapshot) * + An existing PVC (PersistentVolumeClaim) If + the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. If the AnyVolumeDataSource + feature gate is enabled, this field will always + have the same contents as the DataSourceRef + field.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'Specifies the object from which + to populate the volume with data, if a non-empty + volume is desired. This may be any local object + from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this + field is specified, volume binding will only + succeed if the type of the specified object + matches some installed volume populator or + dynamic provisioner. This field will replace + the functionality of the DataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, both fields (DataSource and + DataSourceRef) will be set to the same value + automatically if one of them is empty and + the other is non-empty. There are two important + differences between DataSource and DataSourceRef: + * While DataSource only allows two specific + types of objects, DataSourceRef allows any + non-core object, as well as PersistentVolumeClaim + objects. * While DataSource ignores disallowed + values (dropping them), DataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. (Alpha) Using this field + requires the AnyVolumeDataSource feature gate + to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + resources: + description: 'Resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: A label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'Name of the StorageClass required + by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: VolumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: FC represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: Driver is the name of the driver to use + for this volume. + type: string + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". The default filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command options if any.' + type: object + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef is reference to the + secret object containing sensitive information to + pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the + plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: Name of the dataset stored as metadata + -> name on the dataset for Flocker should be considered + as deprecated + type: string + datasetUUID: + description: UUID of the dataset. This is unique identifier + of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'The partition in the volume that you want + to mount. If omitted, the default is to mount by volume + name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property + empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD resource in GCE. + Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. Must not contain + or start with '..'. If '.' is supplied, the volume + directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'Path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator Name. If initiatorName + is specified with iscsiInterface simultaneously, new + iSCSI interface : will + be created for the connection. + type: string + iqn: + description: Target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iSCSI Interface Name that uses an iSCSI + transport. Defaults to 'default' (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. The portal is + either an IP or ip_addr:port if the port is other + than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI target and initiator + authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. The Portal is either + an IP or ip_addr:port if the port is other than default + (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + pdID: + description: ID that identifies Photon Controller persistent + disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: FSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources secrets, configmaps, + and downward API + properties: + defaultMode: + description: Mode bits used to set permissions on created + files by default. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. Directories within the + path are not affected by this setting. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: information about the configMap data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + downwardAPI: + description: information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about the secret data + to project + properties: + items: + description: If unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used + to set permissions on this file. Must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be + an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + type: object + serviceAccountToken: + description: information about the serviceAccountToken + data to project + properties: + audience: + description: Audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: Path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: Quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: Group to map volume access to Default is + no group + type: string + readOnly: + description: ReadOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: Registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: Tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: User to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: Volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the volume that you + want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph monitors. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. Default is rbd. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'The rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: The host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO Protection Domain + for the configured storage. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: Indicates whether the storage for a volume + should be ThickProvisioned or ThinProvisioned. Default + is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool associated with + the protection domain. + type: string + system: + description: The name of the storage system as configured + in ScaleIO. + type: string + volumeName: + description: The name of a volume already created in + the ScaleIO system that is associated with this volume + source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits used to set permissions + on created files by default. Must be an octal value + between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults + to 0644. Directories within the path are not affected + by this setting. This might be in conflict with other + options that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start + with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set + permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the file to + map the key to. May not be an absolute path. + May not contain the path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret or its keys + must be defined + type: boolean + secretName: + description: 'Name of the secret in the pod''s namespace + to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + readOnly: + description: Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. Must be a filesystem + type supported by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + storagePolicyID: + description: Storage Policy Based Management (SPBM) + profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based Management (SPBM) + profile name. + type: string + volumePath: + description: Path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + repositoryCredentials: + description: RepositoryCredentials are the Git pull credentials to + configure Argo CD with upon creation of the cluster. + type: string + resourceActions: + description: ResourceActions customizes resource action behavior. + items: + description: Resource Customization for custom action + properties: + action: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceCustomizations: + description: 'ResourceCustomizations customizes resource behavior. + Keys are in the form: group/Kind. Please note that this is being + deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' + type: string + resourceExclusions: + description: ResourceExclusions is used to completely ignore entire + classes of resource group/kinds. + type: string + resourceHealthChecks: + description: ResourceHealthChecks customizes resource health check + behavior. + items: + description: Resource Customization for custom health check + properties: + check: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceIgnoreDifferences: + description: ResourceIgnoreDifferences customizes resource ignore + difference behavior. + properties: + all: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + resourceIdentifiers: + items: + description: Resource Customization fields for ignore difference + properties: + customization: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + group: + type: string + kind: + type: string + type: object + type: array + type: object + resourceInclusions: + description: ResourceInclusions is used to only include specific group/kinds + in the reconciliation process. + type: string + resourceTrackingMethod: + description: ResourceTrackingMethod defines how Argo CD should track + resources that it manages + type: string + server: + description: Server defines the options for the ArgoCD Server component. + properties: + autoscale: + description: Autoscale defines the autoscale options for the Argo + CD Server component. + properties: + enabled: + description: Enabled will toggle autoscaling support for the + Argo CD Server component. + type: boolean + hpa: + description: HPA defines the HorizontalPodAutoscaler options + for the Argo CD Server component. + properties: + maxReplicas: + description: upper limit for the number of pods that can + be set by the autoscaler; cannot be smaller than MinReplicas. + format: int32 + type: integer + minReplicas: + description: minReplicas is the lower limit for the number + of replicas to which the autoscaler can scale down. It + defaults to 1 pod. minReplicas is allowed to be 0 if + the alpha feature gate HPAScaleToZero is enabled and + at least one Object or External metric is configured. Scaling + is active as long as at least one metric value is available. + format: int32 + type: integer + scaleTargetRef: + description: reference to scaled resource; horizontal + pod autoscaler will learn the current resource consumption + and will set the desired number of pods by using its + Scale subresource. + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + type: string + name: + description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + required: + - kind + - name + type: object + targetCPUUtilizationPercentage: + description: target average CPU utilization (represented + as a percentage of requested CPU) over all the pods; + if not specified the default autoscaling policy will + be used. + format: int32 + type: integer + required: + - maxReplicas + - scaleTargetRef + type: object + required: + - enabled + type: object + env: + description: Env lets you specify environment for API server pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: Extra Command arguments that would append to the + Argo CD server command. ExtraCommandArgs will not be added, + if one of these commands is already part of the server command + with same or different value. + items: + type: string + type: array + grpc: + description: GRPC defines the state for the Argo CD Server GRPC + options. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for the Argo + CD Server GRPC Ingress. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included + in the TLS certificate. The values in this list + must match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + type: object + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an Ingress. + properties: + hosts: + description: Hosts are a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: SecretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + Host header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + insecure: + description: Insecure toggles the insecure flag. + type: boolean + logFormat: + description: LogFormat refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if + not set. Valid options are debug, info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas for argocd-server. + Default is nil. Value should be greater than or equal to 0. + Value will be ignored if Autoscaler is enabled. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for the Argo CD server component. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + service: + description: Service defines the options for the Service backing + the ArgoCD Server component. + properties: + type: + description: Type is the ServiceType to use for the Service + resource. + type: string + required: + - type + type: object + type: object + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sso: + description: SSO defines the Single Sign-on configuration for Argo + CD + properties: + dex: + description: Dex contains the configuration for Argo CD dex authentication + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must + be a member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + image: + description: Deprecated field. Support dropped in v1beta1 version. + Image is the SSO container image. + type: string + keycloak: + description: Keycloak contains the configuration for Argo CD keycloak + authentication + properties: + image: + description: Image is the Keycloak container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Keycloak. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + rootCA: + description: Custom root CA certificate for communicating + with the Keycloak OIDC provider + type: string + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the Keycloak container image tag. + type: string + type: object + provider: + description: Provider installs and configures the given SSO Provider + with Argo CD. + type: string + resources: + description: Deprecated field. Support dropped in v1beta1 version. + Resources defines the Compute Resources required by the container + for SSO. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + verifyTLS: + description: Deprecated field. Support dropped in v1beta1 version. + VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Deprecated field. Support dropped in v1beta1 version. + Version is the SSO container image tag. + type: string + type: object + statusBadgeEnabled: + description: StatusBadgeEnabled toggles application status badge feature. + type: boolean + tls: + description: TLS defines the TLS options for ArgoCD. + properties: + ca: + description: CA defines the CA options. + properties: + configMapName: + description: ConfigMapName is the name of the ConfigMap containing + the CA Certificate. + type: string + secretName: + description: SecretName is the name of the Secret containing + the CA Certificate and Key. + type: string + type: object + initialCerts: + additionalProperties: + type: string + description: InitialCerts defines custom TLS certificates upon + creation of the cluster for connecting Git repositories via + HTTPS. + type: object + type: object + usersAnonymousEnabled: + description: UsersAnonymousEnabled toggles anonymous user access. + The anonymous users get default role permissions specified argocd-rbac-cm. + type: boolean + version: + description: Version is the tag to use with the ArgoCD container image + for all ArgoCD components. + type: string + type: object + status: + description: ArgoCDStatus defines the observed state of ArgoCD + properties: + applicationController: + description: 'ApplicationController is a simple, high-level summary + of where the Argo CD application controller component is in its + lifecycle. There are four possible ApplicationController values: + Pending: The Argo CD application controller component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD application controller component are in a Ready state. Failed: + At least one of the Argo CD application controller component Pods + had a failure. Unknown: The state of the Argo CD application controller + component could not be obtained.' + type: string + applicationSetController: + description: 'ApplicationSetController is a simple, high-level summary + of where the Argo CD applicationSet controller component is in its + lifecycle. There are four possible ApplicationSetController values: + Pending: The Argo CD applicationSet controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD applicationSet controller component are in a Ready + state. Failed: At least one of the Argo CD applicationSet controller + component Pods had a failure. Unknown: The state of the Argo CD + applicationSet controller component could not be obtained.' + type: string + host: + description: Host is the hostname of the Ingress. + type: string + notificationsController: + description: 'NotificationsController is a simple, high-level summary + of where the Argo CD notifications controller component is in its + lifecycle. There are four possible NotificationsController values: + Pending: The Argo CD notifications controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD notifications controller component are in a Ready + state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD + notifications controller component could not be obtained.' + type: string + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCD + is in its lifecycle. There are four possible phase values: Pending: + The ArgoCD has been accepted by the Kubernetes system, but one or + more of the required resources have not been created. Available: + All of the resources for the ArgoCD are ready. Failed: At least + one resource has experienced a failure. Unknown: The state of the + ArgoCD phase could not be obtained.' + type: string + redis: + description: 'Redis is a simple, high-level summary of where the Argo + CD Redis component is in its lifecycle. There are four possible + redis values: Pending: The Argo CD Redis component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Redis component are in a Ready state. Failed: At least one + of the Argo CD Redis component Pods had a failure. Unknown: The + state of the Argo CD Redis component could not be obtained.' + type: string + redisTLSChecksum: + description: RedisTLSChecksum contains the SHA256 checksum of the + latest known state of tls.crt and tls.key in the argocd-operator-redis-tls + secret. + type: string + repo: + description: 'Repo is a simple, high-level summary of where the Argo + CD Repo component is in its lifecycle. There are four possible repo + values: Pending: The Argo CD Repo component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Repo component are in a Ready state. Failed: At least one + of the Argo CD Repo component Pods had a failure. Unknown: The + state of the Argo CD Repo component could not be obtained.' + type: string + repoTLSChecksum: + description: RepoTLSChecksum contains the SHA256 checksum of the latest + known state of tls.crt and tls.key in the argocd-repo-server-tls + secret. + type: string + server: + description: 'Server is a simple, high-level summary of where the + Argo CD server component is in its lifecycle. There are four possible + server values: Pending: The Argo CD server component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD server component are in a Ready state. Failed: At least + one of the Argo CD server component Pods had a failure. Unknown: + The state of the Argo CD server component could not be obtained.' + type: string + sso: + description: 'SSO is a simple, high-level summary of where the Argo + CD SSO(Dex/Keycloak) component is in its lifecycle. There are four + possible sso values: Pending: The Argo CD SSO component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD SSO component are in a Ready state. Failed: At least + one of the Argo CD SSO component Pods had a failure. Unknown: The + state of the Argo CD SSO component could not be obtained.' + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: description: ArgoCD is the Schema for the argocds API diff --git a/docs/install/manual.md b/docs/install/manual.md index 434b4f8d4..79fb7cdc3 100644 --- a/docs/install/manual.md +++ b/docs/install/manual.md @@ -29,6 +29,76 @@ manifests. Note that these steps generates the manifests using kustomize. By default, the operator is installed into the `argocd-operator-system` namespace. To modify this, update the value of the `namespace` specified in the `config/default/kustomization.yaml` file. +### Conversion Webhook Support + +ArgoCD `v1alpha1` CRD has been **deprecated** starting from **argocd-operator v0.8.0**. To facilitate automatic migration of existing v1alpha1 ArgoCD CRs to v1beta1, conversion webhook support has been introduced. + +By default, the conversion webhook is disabled for the manual(non-OLM) installation of the operator. Users can modify the configurations to enable conversion webhook support using the instructions provided below. + +!!! warning + Enabling the webhook is optional. However, without conversion webhook support, users are responsible for migrating any existing ArgoCD v1alpha1 CRs to v1beta1. + +##### Enable Webhook Support + +To enable the operator to utilize the `cert-manager` for automated webhook certificate management, ensure that it is installed in the cluster. Use [this](https://cert-manager.io/docs/installation/) guide to install `cert-manager` if not present on the cluster. + +Add cert-manager annotation to CRD in `config/crd/patches/cainjection_in_argocds.yaml` file. +```yaml +metadata: + name: argocds.argoproj.io + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +``` + +Enable `../certmanager` directory under the `bases` section in `config/default/kustomization.yaml` file. +```yaml +bases: +..... +- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +- ../certmanager +``` + +Enable all the `vars` under the `[CERTMANAGER]` section in `config/default/kustomization.yaml` file. +```yaml +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace +- name: CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service +``` + +Additionally, set the `ENABLE_CONVERSION_WEBHOOK` environment variable in `config/default/manager_webhook_patch.yaml` file to enable the conversion webhook. +```yaml + - name: manager + env: + - name: ENABLE_CONVERSION_WEBHOOK + value: "true" +``` + ### Deploy Operator Deploy the operator. This will create all the necessary resources, including the namespace. For running the make command you need to install go-lang package on your system. diff --git a/docs/install/openshift.md b/docs/install/openshift.md index d1467a62c..b2567df45 100644 --- a/docs/install/openshift.md +++ b/docs/install/openshift.md @@ -36,6 +36,45 @@ oc login -u kubeadmin By default, the operator is installed into the `argocd-operator-system` namespace. To modify this, update the value of the `namespace` specified in the `config/default/kustomization.yaml` file. +### Conversion Webhook Support + +ArgoCD `v1alpha1` CRD has been **deprecated** starting from **argocd-operator v0.8.0**. To facilitate automatic migration of existing `v1alpha1` ArgoCD CRs to `v1beta1`, conversion webhook support has been introduced. + +By default, the conversion webhook is disabled for the manual(non-OLM) installation of the operator. Users can modify the configurations to enable conversion webhook support using the instructions provided below. + +!!! warning + Enabling the webhook is optional. However, without conversion webhook support, users are responsible for migrating any existing ArgoCD v1alpha1 CRs to v1beta1. + +##### Enable Webhook Support + +To enable the operator to utilize the `Openshift Service CA Operator` for automated webhook certificate management, add following annotations. + +`config/webhook/service.yaml` +```yaml +metadata: + name: webhook-service + annotations: + service.beta.openshift.io/serving-cert-secret-name: webhook-server-cert +``` + +`config/crd/patches/cainjection_in_argocds.yaml` +```yaml +metadata: + name: argocds.argoproj.io + annotations: + service.beta.openshift.io/inject-cabundle: true +``` + +Additionally, set the `ENABLE_CONVERSION_WEBHOOK`` environment variable in the operator to enable the conversion webhook. + +`config/default/manager_webhook_patch.yaml` +```yaml + - name: manager + env: + - name: ENABLE_CONVERSION_WEBHOOK + value: "true" +``` + ### Deploy Operator Deploy the operator. This will create all the necessary resources, including the namespace. For running the make command you need to install go-lang package on your system. diff --git a/main.go b/main.go index 828e5b0f6..d04c90e45 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" - argoprojiov1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + v1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + v1beta1 "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/version" //+kubebuilder:scaffold:imports ) @@ -62,7 +63,8 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(argoprojiov1alpha1.AddToScheme(scheme)) + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + utilruntime.Must(v1beta1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } @@ -132,7 +134,12 @@ func main() { setupLog.Info("Registering Components.") // Setup Scheme for all resources - if err := argoprojiov1alpha1.AddToScheme(mgr.GetScheme()); err != nil { + if err := v1alpha1.AddToScheme(mgr.GetScheme()); err != nil { + setupLog.Error(err, "") + os.Exit(1) + } + + if err := v1beta1.AddToScheme(mgr.GetScheme()); err != nil { setupLog.Error(err, "") os.Exit(1) } @@ -191,6 +198,14 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "ArgoCDExport") os.Exit(1) } + + // Start webhook only if ENABLE_CONVERSION_WEBHOOK is set + if strings.EqualFold(os.Getenv("ENABLE_CONVERSION_WEBHOOK"), "true") { + if err = (&v1beta1.ArgoCD{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "ArgoCD") + os.Exit(1) + } + } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/tests/olm/1-001_alpha_to_beta_dex_conversion/01-argocd-dex.yaml b/tests/olm/1-001_alpha_to_beta_dex_conversion/01-argocd-dex.yaml new file mode 100644 index 000000000..0a9510b83 --- /dev/null +++ b/tests/olm/1-001_alpha_to_beta_dex_conversion/01-argocd-dex.yaml @@ -0,0 +1,12 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + dex: + openShiftOAuth: true + server: + route: + enabled: true \ No newline at end of file diff --git a/tests/olm/1-001_alpha_to_beta_dex_conversion/01-assert.yaml b/tests/olm/1-001_alpha_to_beta_dex_conversion/01-assert.yaml new file mode 100644 index 000000000..6abd5502a --- /dev/null +++ b/tests/olm/1-001_alpha_to_beta_dex_conversion/01-assert.yaml @@ -0,0 +1,17 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + server: + route: + enabled: true +status: + phase: Available + sso: Running diff --git a/tests/olm/1-001_alpha_to_beta_dex_conversion/02-delete.yaml b/tests/olm/1-001_alpha_to_beta_dex_conversion/02-delete.yaml new file mode 100644 index 000000000..fd9f5918a --- /dev/null +++ b/tests/olm/1-001_alpha_to_beta_dex_conversion/02-delete.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: argoproj.io/v1alpha1 + kind: ArgoCD + metadata: + name: argocd \ No newline at end of file diff --git a/tests/olm/1-001_alpha_to_beta_dex_conversion/02-errors.yaml b/tests/olm/1-001_alpha_to_beta_dex_conversion/02-errors.yaml new file mode 100644 index 000000000..679f5d2f8 --- /dev/null +++ b/tests/olm/1-001_alpha_to_beta_dex_conversion/02-errors.yaml @@ -0,0 +1,14 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + server: + route: + enabled: true diff --git a/tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-argocd-keycloak.yaml b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-argocd-keycloak.yaml new file mode 100644 index 000000000..d0dbc39c5 --- /dev/null +++ b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-argocd-keycloak.yaml @@ -0,0 +1,12 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: keycloak +spec: + sso: + provider: keycloak + verifyTLS: false + extraConfig: + oidc.tls.insecure.skip.verify: 'true' \ No newline at end of file diff --git a/tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-assert.yaml b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-assert.yaml new file mode 100644 index 000000000..fae21b94a --- /dev/null +++ b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/01-assert.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: keycloak +spec: + sso: + provider: keycloak + keycloak: + verifyTLS: false + extraConfig: + oidc.tls.insecure.skip.verify: 'true' +status: + phase: Available + #sso: Running diff --git a/tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-delete.yaml b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-delete.yaml new file mode 100644 index 000000000..2948f6512 --- /dev/null +++ b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-delete.yaml @@ -0,0 +1,9 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: argoproj.io/v1alpha1 + kind: ArgoCD + metadata: + name: argocd + labels: + example: keycloak \ No newline at end of file diff --git a/tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-errors.yaml b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-errors.yaml new file mode 100644 index 000000000..e6825d703 --- /dev/null +++ b/tests/olm/1-002_alpha_to_beta_keycloak_conversion/02-errors.yaml @@ -0,0 +1,13 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: keycloak +spec: + sso: + provider: keycloak + keycloak: + verifyTLS: false + extraConfig: + oidc.tls.insecure.skip.verify: 'true' diff --git a/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-argocd-dex-keycloak-conflict.yaml b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-argocd-dex-keycloak-conflict.yaml new file mode 100644 index 000000000..e3a8a926f --- /dev/null +++ b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-argocd-dex-keycloak-conflict.yaml @@ -0,0 +1,17 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex-keycloak +spec: + # during conversion deprecated dex field has more priority + dex: + openShiftOAuth: true + sso: + provider: keycloak + keycloak: + rootCA: '"---BEGIN---END---"' + verifyTLS: false + extraConfig: + oidc.tls.insecure.skip.verify: 'true' \ No newline at end of file diff --git a/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-assert.yaml b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-assert.yaml new file mode 100644 index 000000000..cbcc0ae51 --- /dev/null +++ b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/01-assert.yaml @@ -0,0 +1,20 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex-keycloak +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + keycloak: + rootCA: '"---BEGIN---END---"' + verifyTLS: false + extraConfig: + oidc.tls.insecure.skip.verify: 'true' +status: + phase: Available + sso: Failed + diff --git a/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-delete.yaml b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-delete.yaml new file mode 100644 index 000000000..fd9f5918a --- /dev/null +++ b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-delete.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: argoproj.io/v1alpha1 + kind: ArgoCD + metadata: + name: argocd \ No newline at end of file diff --git a/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-errors.yaml b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-errors.yaml new file mode 100644 index 000000000..9a3384590 --- /dev/null +++ b/tests/olm/1-003_alpha_to_beta_sso_conflict_conversion/02-errors.yaml @@ -0,0 +1,17 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex-keycloak +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + keycloak: + rootCA: '"---BEGIN---END---"' + verifyTLS: false + extraConfig: + oidc.tls.insecure.skip.verify: 'true' + diff --git a/tests/olm/1-004_beta_to_alpha_conversion/01-argocd-dex.yaml b/tests/olm/1-004_beta_to_alpha_conversion/01-argocd-dex.yaml new file mode 100644 index 000000000..e52c8f245 --- /dev/null +++ b/tests/olm/1-004_beta_to_alpha_conversion/01-argocd-dex.yaml @@ -0,0 +1,14 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + server: + route: + enabled: true \ No newline at end of file diff --git a/tests/olm/1-004_beta_to_alpha_conversion/01-assert.yaml b/tests/olm/1-004_beta_to_alpha_conversion/01-assert.yaml new file mode 100644 index 000000000..57949bb18 --- /dev/null +++ b/tests/olm/1-004_beta_to_alpha_conversion/01-assert.yaml @@ -0,0 +1,25 @@ +# During beta to alpha conversion, converting sso fields back to deprecated fields is ignored as +# there is no data loss since the new fields in v1beta1 are also present in v1alpha1 +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + server: + route: + enabled: true +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-dex-server +status: + readyReplicas: 1 diff --git a/tests/olm/1-004_beta_to_alpha_conversion/02-delete.yaml b/tests/olm/1-004_beta_to_alpha_conversion/02-delete.yaml new file mode 100644 index 000000000..fd9f5918a --- /dev/null +++ b/tests/olm/1-004_beta_to_alpha_conversion/02-delete.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: argoproj.io/v1alpha1 + kind: ArgoCD + metadata: + name: argocd \ No newline at end of file diff --git a/tests/olm/1-004_beta_to_alpha_conversion/02-errors.yaml b/tests/olm/1-004_beta_to_alpha_conversion/02-errors.yaml new file mode 100644 index 000000000..795b1c07b --- /dev/null +++ b/tests/olm/1-004_beta_to_alpha_conversion/02-errors.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + server: + route: + enabled: true +--- +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: argocd + labels: + example: dex +spec: + sso: + provider: dex + dex: + openShiftOAuth: true + server: + route: + enabled: true +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-dex-server diff --git a/tests/olm/README.md b/tests/olm/README.md new file mode 100644 index 000000000..c84dc4bb6 --- /dev/null +++ b/tests/olm/README.md @@ -0,0 +1,85 @@ +## OLM Installed Operator + +This folder contains tests which need operator installed via OLM + +#### Steps for local testing via OLM + +##### Setup local k8s cluster + +```bash +# create local image registry +k3d registry create registry.localhost --port 12345 + +# ensure that below "k3d-registry.localhost" entry is present in your /etc/hosts file for registry domain resolution +$ cat /etc/hosts +...... +...... +...... +127.0.0.1 k3d-registry.localhost + +# create a new cluster that uses this registry +k3d cluster create test --registry-use k3d-registry.localhost:12345 +``` + +##### Build and install the operator + +```bash +# install olm on target cluster +operator-sdk olm install + +# env setup +export REGISTRY="k3d-registry.localhost:12345" +export ORG="local" +export CONTROLLER_IMAGE="argocd-operator:test" +export BUNDLE_IMAGE="argocd-operator-bundle:test" +export VERSION="0.7.0" +export CATALOG_IMAGE=argocd-operator-catalog +export CATALOG_TAG=v0.7.0 + +# build and push operator image +make generate +make manifests +make docker-build IMG="$REGISTRY/$ORG/$CONTROLLER_IMAGE" +docker push "$REGISTRY/$ORG/$CONTROLLER_IMAGE" + +# build and push bundle image +make bundle IMG="$REGISTRY/$ORG/$CONTROLLER_IMAGE" +make bundle-build BUNDLE_IMG="$REGISTRY/$ORG/$BUNDLE_IMAGE" +docker push "$REGISTRY/$ORG/$BUNDLE_IMAGE" + +# validate bundle +operator-sdk bundle validate "$REGISTRY/$ORG/$BUNDLE_IMAGE" + +# skip catalog and install operator on target cluster via operator-sdk +#operator-sdk run bundle "$REGISTRY/$ORG/$BUNDLE_IMAGE" -n operators + +# build and push catalog image +make catalog-build CATALOG_IMG="$REGISTRY/$ORG/$CATALOG_IMAGE:$CATALOG_TAG" BUNDLE_IMGS="$REGISTRY/$ORG/$BUNDLE_IMAGE" +docker push "$REGISTRY/$ORG/$CATALOG_IMAGE:$CATALOG_TAG" + +# install catalog +sed "s/image:.*/image: $REGISTRY\/$ORG\/$CATALOG_IMAGE:$CATALOG_TAG/" deploy/catalog_source.yaml | kubectl apply -n operators -f - + +# create subscription +sed "s/sourceNamespace:.*/sourceNamespace: operators/" deploy/subscription.yaml | kubectl apply -n operators -f - +``` + +##### Run tests + +```bash +# wait till argocd-operator-controller-manager pod is in running state +kubectl -n operators get all + +kubectl kuttl test ./tests/olm --config ./tests/kuttl-tests.yaml +``` + +##### Cleanup + +```bash +operator-sdk cleanup argocd-operator -n operators +kubectl delete clusterserviceversion/argocd-operator.v0.7.0 -n operators +make uninstall + +k3d cluster delete test +k3d registry delete registry.localhost +``` \ No newline at end of file From c658019f37589cc4a3c1e8dc0dd346d7b7283e4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:41:05 -0400 Subject: [PATCH 08/94] chore(deps): bump pygments from 2.7.4 to 2.15.0 in /docs (#950) Bumps [pygments](https://github.com/pygments/pygments) from 2.7.4 to 2.15.0. - [Release notes](https://github.com/pygments/pygments/releases) - [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES) - [Commits](https://github.com/pygments/pygments/compare/2.7.4...2.15.0) --- updated-dependencies: - dependency-name: pygments dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index ffc899a94..d84098727 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ mkdocs==1.2.3 mkdocs-material==7.1.7 -pygments==2.7.4 +pygments==2.15.0 jinja2===3.0.3 From e49612a4cf93bb3d125eac2cbb8fac2c032b7970 Mon Sep 17 00:00:00 2001 From: Abhishek Veeramalla Date: Mon, 28 Aug 2023 14:28:29 +0530 Subject: [PATCH 09/94] feat: upgrade RH-SSO from 7.5 to 7.6 (#977) * upgrade RH-SSO from 7.5 to 7.6 Signed-off-by: iam-veeramalla * fix: failing tests Signed-off-by: iam-veeramalla * fix: failing tests Signed-off-by: iam-veeramalla --------- Signed-off-by: iam-veeramalla --- common/defaults.go | 6 +++--- controllers/argocd/keycloak.go | 19 ++++++++++++++++--- controllers/argocd/keycloak_test.go | 12 ++++++++++-- docs/reference/argocd.md | 2 +- examples/argocd-keycloak-openshift.yaml | 8 ++++++-- tests/ocp/1-001_validate_rhsso/01-assert.yaml | 2 +- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/common/defaults.go b/common/defaults.go index 1a538bc39..118b95e32 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -183,11 +183,11 @@ const ( ArgoCDKeycloakVersion = "sha256:64fb81886fde61dee55091e6033481fa5ccdac62ae30a4fd29b54eb5e97df6a9" // ArgoCDKeycloakImageForOpenShift is the default Keycloak Image used for the OpenShift platform when not specified. - ArgoCDKeycloakImageForOpenShift = "registry.redhat.io/rh-sso-7/sso75-openshift-rhel8" + ArgoCDKeycloakImageForOpenShift = "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8" // ArgoCDKeycloakVersionForOpenShift is the default Keycloak version used for the OpenShift platform when not specified. - // Version: 7.5.1 - ArgoCDKeycloakVersionForOpenShift = "sha256:720a7e4c4926c41c1219a90daaea3b971a3d0da5a152a96fed4fb544d80f52e3" + // Version: 7.6-25 + ArgoCDKeycloakVersionForOpenShift = "sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d" // ArgoCDDefaultOIDCConfig is the default OIDC configuration. ArgoCDDefaultOIDCConfig = "" diff --git a/controllers/argocd/keycloak.go b/controllers/argocd/keycloak.go index 4c525d3ce..36d100cfa 100644 --- a/controllers/argocd/keycloak.go +++ b/controllers/argocd/keycloak.go @@ -282,7 +282,7 @@ func getKeycloakContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { Image: getKeycloakContainerImage(cr), ImagePullPolicy: "Always", LivenessProbe: &corev1.Probe{ - FailureThreshold: 3, + TimeoutSeconds: 120, ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ Command: []string{ @@ -302,7 +302,7 @@ func getKeycloakContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { {ContainerPort: 8888, Name: "ping", Protocol: "TCP"}, }, ReadinessProbe: &corev1.Probe{ - FailureThreshold: 20, + TimeoutSeconds: 120, ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ Command: []string{ @@ -312,7 +312,6 @@ func getKeycloakContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { }, }, }, - InitialDelaySeconds: 60, }, Resources: getKeycloakResources(cr), VolumeMounts: []corev1.VolumeMount{ @@ -326,12 +325,18 @@ func getKeycloakContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { Name: "service-ca", ReadOnly: true, }, + { + Name: "sso-probe-netrc-volume", + MountPath: "/mnt/rh-sso", + ReadOnly: false, + }, }, } } func getKeycloakDeploymentConfigTemplate(cr *argoprojv1a1.ArgoCD) *appsv1.DeploymentConfig { ns := cr.Namespace + var medium corev1.StorageMedium = "Memory" keycloakContainer := getKeycloakContainer(cr) dc := &appsv1.DeploymentConfig{ @@ -401,6 +406,14 @@ func getKeycloakDeploymentConfigTemplate(cr *argoprojv1a1.ArgoCD) *appsv1.Deploy }, }, }, + { + Name: "sso-probe-netrc-volume", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: medium, + }, + }, + }, }, NodeSelector: common.DefaultNodeSelector(), }, diff --git a/controllers/argocd/keycloak_test.go b/controllers/argocd/keycloak_test.go index 80d759ff2..6952ecf58 100644 --- a/controllers/argocd/keycloak_test.go +++ b/controllers/argocd/keycloak_test.go @@ -55,6 +55,14 @@ var ( }, }, }, + { + Name: "sso-probe-netrc-volume", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: "Memory", + }, + }, + }, } ) @@ -107,7 +115,7 @@ func TestKeycloakContainerImage(t *testing.T) { }), updateCrFunc: nil, templateAPIFound: true, - wantContainerImage: "registry.redhat.io/rh-sso-7/sso75-openshift-rhel8@sha256:720a7e4c4926c41c1219a90daaea3b971a3d0da5a152a96fed4fb544d80f52e3", + wantContainerImage: "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d", }, { name: "ArgoCDKeycloakImageEnvName env var set", @@ -243,7 +251,7 @@ func TestNewKeycloakTemplate_testKeycloakContainer(t *testing.T) { } kc := getKeycloakContainer(a) assert.Equal(t, - "registry.redhat.io/rh-sso-7/sso75-openshift-rhel8@sha256:720a7e4c4926c41c1219a90daaea3b971a3d0da5a152a96fed4fb544d80f52e3", kc.Image) + "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d", kc.Image) assert.Equal(t, corev1.PullAlways, kc.ImagePullPolicy) assert.Equal(t, "${APPLICATION_NAME}", kc.Name) } diff --git a/docs/reference/argocd.md b/docs/reference/argocd.md index 736b21072..7aa0e1db8 100644 --- a/docs/reference/argocd.md +++ b/docs/reference/argocd.md @@ -1539,7 +1539,7 @@ The following properties are available for configuring Keycloak Single sign-on p Name | Default | Description --- | --- | --- -Image | OpenShift - `registry.redhat.io/rh-sso-7/sso75-openshift-rhel8`
Kuberentes - `quay.io/keycloak/keycloak` | The container image for keycloak. This overrides the `ARGOCD_KEYCLOAK_IMAGE` environment variable. +Image | OpenShift - `registry.redhat.io/rh-sso-7/sso76-openshift-rhel8`
Kuberentes - `quay.io/keycloak/keycloak` | The container image for keycloak. This overrides the `ARGOCD_KEYCLOAK_IMAGE` environment variable. Resources | `Requests`: CPU=500m, Mem=512Mi, `Limits`: CPU=1000m, Mem=1024Mi | The container compute resources. RootCA | "" | root CA certificate for communicating with the OIDC provider VerifyTLS | true | Whether to enforce strict TLS checking when communicating with Keycloak service. diff --git a/examples/argocd-keycloak-openshift.yaml b/examples/argocd-keycloak-openshift.yaml index 745bf17ea..3af6cb8e5 100644 --- a/examples/argocd-keycloak-openshift.yaml +++ b/examples/argocd-keycloak-openshift.yaml @@ -3,10 +3,14 @@ kind: ArgoCD metadata: name: example-argocd spec: + extraConfig: + oidc.tls.insecure.skip.verify: 'true' sso: provider: keycloak - # uncomment the below line when running operator locally. - # verifyTLS: false + keycloak: + rootCA: "---BEGIN---END---" + # Uncomment the below line when running operator locally. + # verifyTLS: false server: route: enabled: true diff --git a/tests/ocp/1-001_validate_rhsso/01-assert.yaml b/tests/ocp/1-001_validate_rhsso/01-assert.yaml index dce8574ce..c0586f98b 100644 --- a/tests/ocp/1-001_validate_rhsso/01-assert.yaml +++ b/tests/ocp/1-001_validate_rhsso/01-assert.yaml @@ -33,7 +33,7 @@ spec: name: keycloak spec: containers: - - image: registry.redhat.io/rh-sso-7/sso75-openshift-rhel8@sha256:720a7e4c4926c41c1219a90daaea3b971a3d0da5a152a96fed4fb544d80f52e3 + - image: registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d resources: limits: cpu: "1" From e624a26efd7223553173c4b4526f7a4292dc3902 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:40:06 +0530 Subject: [PATCH 10/94] refactor: Remove dead code (#979) * Remove dead code Signed-off-by: Siddhesh Ghadi * Fix import Signed-off-by: Siddhesh Ghadi * Fix imports Signed-off-by: Siddhesh Ghadi --------- Signed-off-by: Siddhesh Ghadi --- controllers/argocd/argocd_controller.go | 3 ++- controllers/argocd/role.go | 22 ++++++++++----------- controllers/argocd/role_test.go | 2 +- controllers/argocd/rolebinding.go | 4 ++-- controllers/argocd/sso.go | 9 ++++----- controllers/argocd/testing.go | 26 ------------------------- 6 files changed, 20 insertions(+), 46 deletions(-) diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index e03fd76f8..79e576caa 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -21,9 +21,10 @@ import ( "fmt" "time" - argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" "github.com/prometheus/client_golang/prometheus" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" diff --git a/controllers/argocd/role.go b/controllers/argocd/role.go index d21ffcbce..f7c162c1d 100644 --- a/controllers/argocd/role.go +++ b/controllers/argocd/role.go @@ -31,7 +31,7 @@ func newRole(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.Ro } } -func newRoleForApplicationSourceNamespaces(name, namespace string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.Role { +func newRoleForApplicationSourceNamespaces(namespace string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.Role { return &v1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: getRoleNameForApplicationSourceNamespaces(namespace, cr), @@ -83,7 +83,7 @@ func (r *ReconcileArgoCD) reconcileRoles(cr *argoprojv1a1.ArgoCD) error { log.Info("reconciling roles for source namespaces") policyRuleForApplicationSourceNamespaces := policyRuleForServerApplicationSourceNamespaces() // reconcile roles is source namespaces for ArgoCD Server - if _, err := r.reconcileRoleForApplicationSourceNamespaces(common.ArgoCDServerComponent, policyRuleForApplicationSourceNamespaces, cr); err != nil { + if err := r.reconcileRoleForApplicationSourceNamespaces(common.ArgoCDServerComponent, policyRuleForApplicationSourceNamespaces, cr); err != nil { return err } @@ -186,7 +186,7 @@ func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule return roles, nil } -func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name string, policyRules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) ([]*v1.Role, error) { +func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name string, policyRules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) error { var roles []*v1.Role // create policy rules for each source namespace for ArgoCD Server @@ -194,7 +194,7 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin namespace := &corev1.Namespace{} if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: sourceNamespace}, namespace); err != nil { - return nil, err + return err } // do not reconcile roles for namespaces already containing managed-by label @@ -214,16 +214,16 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin log.Info(fmt.Sprintf("Reconciling role for %s", namespace.Name)) - role := newRoleForApplicationSourceNamespaces(name, namespace.Name, policyRules, cr) + role := newRoleForApplicationSourceNamespaces(namespace.Name, policyRules, cr) if err := applyReconcilerHook(cr, role, ""); err != nil { - return nil, err + return err } role.Namespace = namespace.Name existingRole := v1.Role{} err := r.Client.Get(context.TODO(), types.NamespacedName{Name: role.Name, Namespace: namespace.Name}, &existingRole) if err != nil { if !errors.IsNotFound(err) { - return nil, fmt.Errorf("failed to reconcile the role for the service account associated with %s : %s", name, err) + return fmt.Errorf("failed to reconcile the role for the service account associated with %s : %s", name, err) } } @@ -234,7 +234,7 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin if reflect.DeepEqual(existingRole, v1.Role{}) { log.Info(fmt.Sprintf("creating role %s for Argo CD instance %s in namespace %s", role.Name, cr.Name, namespace)) if err := r.Client.Create(context.TODO(), role); err != nil { - return nil, err + return err } } continue @@ -248,7 +248,7 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin // Get the latest value of namespace before updating it if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: namespace.Name}, namespace); err != nil { - return nil, err + return err } // Update namespace with managed-by-cluster-argocd label namespace.Labels[common.ArgoCDManagedByClusterArgoCDLabel] = cr.Namespace @@ -259,7 +259,7 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin if !reflect.DeepEqual(existingRole.Rules, role.Rules) { existingRole.Rules = role.Rules if err := r.Client.Update(context.TODO(), &existingRole); err != nil { - return nil, err + return err } } roles = append(roles, &existingRole) @@ -269,7 +269,7 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin } } - return roles, nil + return nil } func (r *ReconcileArgoCD) reconcileClusterRole(name string, policyRules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) (*v1.ClusterRole, error) { diff --git a/controllers/argocd/role_test.go b/controllers/argocd/role_test.go index 0129048f6..61c1e13f8 100644 --- a/controllers/argocd/role_test.go +++ b/controllers/argocd/role_test.go @@ -151,7 +151,7 @@ func TestReconcileArgoCD_reconcileRoleForApplicationSourceNamespaces(t *testing. workloadIdentifier := common.ArgoCDServerComponent expectedRules := policyRuleForServerApplicationSourceNamespaces() - _, err := r.reconcileRoleForApplicationSourceNamespaces(workloadIdentifier, expectedRules, a) + err := r.reconcileRoleForApplicationSourceNamespaces(workloadIdentifier, expectedRules, a) assert.NoError(t, err) expectedName := getRoleNameForApplicationSourceNamespaces(sourceNamespace, a) diff --git a/controllers/argocd/rolebinding.go b/controllers/argocd/rolebinding.go index 3f614be64..4be09c3c0 100644 --- a/controllers/argocd/rolebinding.go +++ b/controllers/argocd/rolebinding.go @@ -243,7 +243,7 @@ func (r *ReconcileArgoCD) reconcileRoleBinding(name string, rules []v1.PolicyRul } // get expected name - roleBinding := newRoleBindingWithNameForApplicationSourceNamespaces(name, namespace.Name, cr) + roleBinding := newRoleBindingWithNameForApplicationSourceNamespaces(namespace.Name, cr) roleBinding.Namespace = namespace.Name roleBinding.RoleRef = v1.RoleRef{ @@ -324,7 +324,7 @@ func getRoleNameForApplicationSourceNamespaces(targetNamespace string, cr *argop } // newRoleBindingWithNameForApplicationSourceNamespaces creates a new RoleBinding with the given name for the source namespaces of ArgoCD Server. -func newRoleBindingWithNameForApplicationSourceNamespaces(name, namespace string, cr *argoprojv1a1.ArgoCD) *v1.RoleBinding { +func newRoleBindingWithNameForApplicationSourceNamespaces(namespace string, cr *argoprojv1a1.ArgoCD) *v1.RoleBinding { roleBinding := newRoleBindingForSupportNamespaces(cr, namespace) labels := roleBinding.ObjectMeta.Labels diff --git a/controllers/argocd/sso.go b/controllers/argocd/sso.go index b64b6145f..ee1e77122 100644 --- a/controllers/argocd/sso.go +++ b/controllers/argocd/sso.go @@ -27,11 +27,10 @@ import ( ) const ( - ssoLegalUnknown string = "Unknown" - ssoLegalSuccess string = "Success" - ssoLegalFailed string = "Failed" - illegalSSOConfiguration string = "illegal SSO configuration: " - multipleSSOConfiguration string = "multiple SSO configuration: " + ssoLegalUnknown string = "Unknown" + ssoLegalSuccess string = "Success" + ssoLegalFailed string = "Failed" + illegalSSOConfiguration string = "illegal SSO configuration: " ) var ( diff --git a/controllers/argocd/testing.go b/controllers/argocd/testing.go index ee2e190de..95c884a63 100644 --- a/controllers/argocd/testing.go +++ b/controllers/argocd/testing.go @@ -94,32 +94,6 @@ func makeTestArgoCDForKeycloak() *argoprojv1alpha1.ArgoCD { } return a } -func makeTestArgoCDForKeycloakWithDex(opts ...argoCDOpt) *argoprojv1alpha1.ArgoCD { - a := &argoprojv1alpha1.ArgoCD{ - ObjectMeta: metav1.ObjectMeta{ - Name: testArgoCDName, - Namespace: testNamespace, - }, - Spec: argoprojv1alpha1.ArgoCDSpec{ - SSO: &argoprojv1alpha1.ArgoCDSSOSpec{ - Provider: "keycloak", - Dex: &argoprojv1alpha1.ArgoCDDexSpec{ - OpenShiftOAuth: true, - Resources: makeTestDexResources(), - }, - }, - Server: argoprojv1alpha1.ArgoCDServerSpec{ - Route: argoprojv1alpha1.ArgoCDRouteSpec{ - Enabled: true, - }, - }, - }, - } - for _, o := range opts { - o(a) - } - return a -} func makeTestArgoCDWithResources(opts ...argoCDOpt) *argoprojv1alpha1.ArgoCD { a := &argoprojv1alpha1.ArgoCD{ From e928c0eb91d6c51e2f3f1852e1e52b8f5331b336 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:11:29 +0530 Subject: [PATCH 11/94] Replace ArgoCD v1alpha1 references with v1beta1 (#975) Signed-off-by: Siddhesh Ghadi --- controllers/argocd/applicationset.go | 22 +-- controllers/argocd/applicationset_test.go | 26 +-- controllers/argocd/argocd_controller.go | 2 +- controllers/argocd/argocd_controller_test.go | 8 +- controllers/argocd/configmap.go | 93 +++++---- controllers/argocd/configmap_test.go | 119 ++++++------ controllers/argocd/custommapper.go | 6 +- controllers/argocd/custommapper_test.go | 6 +- controllers/argocd/deployment.go | 51 ++--- controllers/argocd/deployment_test.go | 57 +++--- controllers/argocd/dex.go | 23 ++- controllers/argocd/dexUtil.go | 12 +- controllers/argocd/dex_test.go | 187 +++++++++---------- controllers/argocd/grafana.go | 8 +- controllers/argocd/hooks.go | 6 +- controllers/argocd/hooks_test.go | 10 +- controllers/argocd/hpa.go | 12 +- controllers/argocd/ingress.go | 20 +- controllers/argocd/ingress_test.go | 17 +- controllers/argocd/keycloak.go | 44 ++--- controllers/argocd/keycloak_test.go | 96 +++++----- controllers/argocd/notifications.go | 22 +-- controllers/argocd/notifications_test.go | 18 +- controllers/argocd/notifications_util.go | 4 +- controllers/argocd/prometheus.go | 26 +-- controllers/argocd/prometheus_test.go | 12 +- controllers/argocd/role.go | 22 +-- controllers/argocd/role_test.go | 4 +- controllers/argocd/rolebinding.go | 26 +-- controllers/argocd/rolebinding_test.go | 4 +- controllers/argocd/route.go | 18 +- controllers/argocd/route_test.go | 18 +- controllers/argocd/secret.go | 35 ++-- controllers/argocd/secret_test.go | 11 +- controllers/argocd/service.go | 32 ++-- controllers/argocd/service_account.go | 14 +- controllers/argocd/sso.go | 21 +-- controllers/argocd/sso_test.go | 65 ++++--- controllers/argocd/statefulset.go | 22 +-- controllers/argocd/statefulset_test.go | 27 +-- controllers/argocd/status.go | 30 +-- controllers/argocd/status_test.go | 31 ++- controllers/argocd/testing.go | 38 ++-- controllers/argocd/util.go | 87 +++++---- controllers/argocd/util_test.go | 35 ++-- controllers/argocdexport/export.go | 8 +- controllers/argocdexport/job.go | 26 +-- controllers/argocdexport/local.go | 6 +- controllers/argocdexport/reconcile.go | 3 +- controllers/argocdexport/storage.go | 6 +- controllers/argoutil/resource.go | 9 +- controllers/argoutil/resource_test.go | 6 +- controllers/argoutil/secret.go | 12 +- controllers/suite_testx.go | 7 +- 54 files changed, 760 insertions(+), 770 deletions(-) diff --git a/controllers/argocd/applicationset.go b/controllers/argocd/applicationset.go index e78289129..3aa0e19ec 100644 --- a/controllers/argocd/applicationset.go +++ b/controllers/argocd/applicationset.go @@ -28,13 +28,13 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // getArgoApplicationSetCommand will return the command for the ArgoCD ApplicationSet component. -func getArgoApplicationSetCommand(cr *argoprojv1a1.ArgoCD) []string { +func getArgoApplicationSetCommand(cr *argoproj.ArgoCD) []string { cmd := make([]string, 0) cmd = append(cmd, "entrypoint.sh") @@ -58,7 +58,7 @@ func getArgoApplicationSetCommand(cr *argoprojv1a1.ArgoCD) []string { return cmd } -func (r *ReconcileArgoCD) reconcileApplicationSetController(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileApplicationSetController(cr *argoproj.ArgoCD) error { log.Info("reconciling applicationset serviceaccounts") sa, err := r.reconcileApplicationSetServiceAccount(cr) @@ -91,7 +91,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetController(cr *argoprojv1a1.Arg } // reconcileApplicationControllerDeployment will ensure the Deployment resource is present for the ArgoCD Application Controller component. -func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoprojv1a1.ArgoCD, sa *corev1.ServiceAccount) error { +func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { deploy := newDeploymentWithSuffix("applicationset-controller", "controller", cr) setAppSetLabels(&deploy.ObjectMeta) @@ -185,7 +185,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoprojv1a1.Arg } -func applicationSetContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { +func applicationSetContainer(cr *argoproj.ArgoCD) corev1.Container { // Global proxy env vars go first appSetEnv := []corev1.EnvVar{{ Name: "NAMESPACE", @@ -254,7 +254,7 @@ func applicationSetContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { } } -func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoprojv1a1.ArgoCD) (*corev1.ServiceAccount, error) { +func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { sa := newServiceAccountWithName("applicationset-controller", cr) setAppSetLabels(&sa.ObjectMeta) @@ -283,7 +283,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoprojv1a1 return sa, err } -func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoprojv1a1.ArgoCD) (*v1.Role, error) { +func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoproj.ArgoCD) (*v1.Role, error) { policyRules := []v1.PolicyRule{ @@ -385,7 +385,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoprojv1a1.ArgoCD) ( return role, r.Client.Update(context.TODO(), role) } -func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoprojv1a1.ArgoCD, role *v1.Role, sa *corev1.ServiceAccount) error { +func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoproj.ArgoCD, role *v1.Role, sa *corev1.ServiceAccount) error { name := "applicationset-controller" @@ -428,7 +428,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoprojv1a1.Ar return r.Client.Create(context.TODO(), roleBinding) } -func getApplicationSetContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getApplicationSetContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := "" @@ -458,7 +458,7 @@ func getApplicationSetContainerImage(cr *argoprojv1a1.ArgoCD) string { } // getApplicationSetResources will return the ResourceRequirements for the Application Sets container. -func getApplicationSetResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getApplicationSetResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR @@ -476,7 +476,7 @@ func setAppSetLabels(obj *metav1.ObjectMeta) { } // reconcileApplicationSetService will ensure that the Service is present for the ApplicationSet webhook and metrics component. -func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) error { log.Info("reconciling applicationset service") svc := newServiceWithSuffix(common.ApplicationSetServiceNameSuffix, common.ApplicationSetServiceNameSuffix, cr) diff --git a/controllers/argocd/applicationset_test.go b/controllers/argocd/applicationset_test.go index eb0a7d906..d09f29d3f 100644 --- a/controllers/argocd/applicationset_test.go +++ b/controllers/argocd/applicationset_test.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -74,7 +74,7 @@ func applicationSetDefaultVolumes() []corev1.Volume { func TestReconcileApplicationSet_CreateDeployments(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{} + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} r := makeTestReconciler(t, a) @@ -95,7 +95,7 @@ func TestReconcileApplicationSet_CreateDeployments(t *testing.T) { checkExpectedDeploymentValues(t, deployment, &sa, a) } -func checkExpectedDeploymentValues(t *testing.T, deployment *appsv1.Deployment, sa *corev1.ServiceAccount, a *v1alpha1.ArgoCD) { +func checkExpectedDeploymentValues(t *testing.T, deployment *appsv1.Deployment, sa *corev1.ServiceAccount, a *argoproj.ArgoCD) { assert.Equal(t, deployment.Spec.Template.Spec.ServiceAccountName, sa.ObjectMeta.Name) appsetAssertExpectedLabels(t, &deployment.ObjectMeta) @@ -172,7 +172,7 @@ func TestReconcileApplicationSetProxyConfiguration(t *testing.T) { setProxyEnvVars(t) a := makeTestArgoCD() - a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{} + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} r := makeTestReconciler(t, a) @@ -224,7 +224,7 @@ func TestReconcileApplicationSet_UpdateExistingDeployments(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{} + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} existingDeployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ @@ -305,18 +305,18 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { tests := []struct { name string - appSetField *v1alpha1.ArgoCDApplicationSet + appSetField *argoproj.ArgoCDApplicationSet envVars map[string]string expectedContainerImage string }{ { name: "unspecified fields should use default", - appSetField: &v1alpha1.ArgoCDApplicationSet{}, + appSetField: &argoproj.ArgoCDApplicationSet{}, expectedContainerImage: argoutil.CombineImageTag(common.ArgoCDDefaultArgoImage, common.ArgoCDDefaultArgoVersion), }, { name: "ensure that sha hashes are formatted correctly", - appSetField: &v1alpha1.ArgoCDApplicationSet{ + appSetField: &argoproj.ArgoCDApplicationSet{ Image: "custom-image", Version: "sha256:b835999eb5cf75d01a2678cd971095926d9c2566c9ffe746d04b83a6a0a2849f", }, @@ -324,7 +324,7 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { }, { name: "custom image should properly substitute", - appSetField: &v1alpha1.ArgoCDApplicationSet{ + appSetField: &argoproj.ArgoCDApplicationSet{ Image: "custom-image", Version: "custom-version", }, @@ -332,14 +332,14 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { }, { name: "verify env var substitution overrides default", - appSetField: &v1alpha1.ArgoCDApplicationSet{}, + appSetField: &argoproj.ArgoCDApplicationSet{}, envVars: map[string]string{common.ArgoCDImageEnvName: "custom-env-image"}, expectedContainerImage: "custom-env-image", }, { name: "env var should not override spec fields", - appSetField: &v1alpha1.ArgoCDApplicationSet{ + appSetField: &argoproj.ArgoCDApplicationSet{ Image: "custom-image", Version: "custom-version", }, @@ -500,7 +500,7 @@ func TestReconcileApplicationSet_Service(t *testing.T) { func TestArgoCDApplicationSetCommand(t *testing.T) { a := makeTestArgoCD() - a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{} + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} r := makeTestReconciler(t, a) baseCommand := []string{ @@ -587,7 +587,7 @@ func TestArgoCDApplicationSetCommand(t *testing.T) { func TestArgoCDApplicationSetEnv(t *testing.T) { a := makeTestArgoCD() - a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{} + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} r := makeTestReconciler(t, a) defaultEnv := []corev1.EnvVar{ diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 79e576caa..642dc405c 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -23,7 +23,7 @@ import ( "github.com/prometheus/client_golang/prometheus" - argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" diff --git a/controllers/argocd/argocd_controller_test.go b/controllers/argocd/argocd_controller_test.go index 18a655d97..0cad71c79 100644 --- a/controllers/argocd/argocd_controller_test.go +++ b/controllers/argocd/argocd_controller_test.go @@ -33,7 +33,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - argov1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -171,7 +171,7 @@ func TestReconcileArgoCD_Reconcile_RemoveManagedByLabelOnArgocdDeletion(t *testi } func deletedAt(now time.Time) argoCDOpt { - return func(a *argov1alpha1.ArgoCD) { + return func(a *argoproj.ArgoCD) { wrapped := metav1.NewTime(now) a.ObjectMeta.DeletionTimestamp = &wrapped } @@ -238,12 +238,12 @@ func TestReconcileArgoCD_CleanUp(t *testing.T) { } func addFinalizer(finalizer string) argoCDOpt { - return func(a *argov1alpha1.ArgoCD) { + return func(a *argoproj.ArgoCD) { a.Finalizers = append(a.Finalizers, finalizer) } } -func clusterResources(argocd *argov1alpha1.ArgoCD) []runtime.Object { +func clusterResources(argocd *argoproj.ArgoCD) []runtime.Object { return []runtime.Object{ newClusterRole(common.ArgoCDApplicationControllerComponent, []v1.PolicyRule{}, argocd), newClusterRole(common.ArgoCDServerComponent, []v1.PolicyRule{}, argocd), diff --git a/controllers/argocd/configmap.go b/controllers/argocd/configmap.go index 1afe9c832..e8bf21ea7 100644 --- a/controllers/argocd/configmap.go +++ b/controllers/argocd/configmap.go @@ -27,14 +27,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // createRBACConfigMap will create the Argo CD RBAC ConfigMap resource. -func (r *ReconcileArgoCD) createRBACConfigMap(cm *corev1.ConfigMap, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) createRBACConfigMap(cm *corev1.ConfigMap, cr *argoproj.ArgoCD) error { data := make(map[string]string) data[common.ArgoCDKeyRBACPolicyCSV] = getRBACPolicy(cr) data[common.ArgoCDKeyRBACPolicyDefault] = getRBACDefaultPolicy(cr) @@ -48,7 +47,7 @@ func (r *ReconcileArgoCD) createRBACConfigMap(cm *corev1.ConfigMap, cr *argoproj } // getApplicationInstanceLabelKey will return the application instance label key for the given ArgoCD. -func getApplicationInstanceLabelKey(cr *argoprojv1a1.ArgoCD) string { +func getApplicationInstanceLabelKey(cr *argoproj.ArgoCD) string { key := common.ArgoCDDefaultApplicationInstanceLabelKey if len(cr.Spec.ApplicationInstanceLabelKey) > 0 { key = cr.Spec.ApplicationInstanceLabelKey @@ -57,7 +56,7 @@ func getApplicationInstanceLabelKey(cr *argoprojv1a1.ArgoCD) string { } // getCAConfigMapName will return the CA ConfigMap name for the given ArgoCD. -func getCAConfigMapName(cr *argoprojv1a1.ArgoCD) string { +func getCAConfigMapName(cr *argoproj.ArgoCD) string { if len(cr.Spec.TLS.CA.ConfigMapName) > 0 { return cr.Spec.TLS.CA.ConfigMapName } @@ -65,7 +64,7 @@ func getCAConfigMapName(cr *argoprojv1a1.ArgoCD) string { } // getConfigManagementPlugins will return the config management plugins for the given ArgoCD. -func getConfigManagementPlugins(cr *argoprojv1a1.ArgoCD) string { +func getConfigManagementPlugins(cr *argoproj.ArgoCD) string { plugins := common.ArgoCDDefaultConfigManagementPlugins if len(cr.Spec.ConfigManagementPlugins) > 0 { plugins = cr.Spec.ConfigManagementPlugins @@ -74,7 +73,7 @@ func getConfigManagementPlugins(cr *argoprojv1a1.ArgoCD) string { } // getGATrackingID will return the google analytics tracking ID for the given Argo CD. -func getGATrackingID(cr *argoprojv1a1.ArgoCD) string { +func getGATrackingID(cr *argoproj.ArgoCD) string { id := common.ArgoCDDefaultGATrackingID if len(cr.Spec.GATrackingID) > 0 { id = cr.Spec.GATrackingID @@ -83,7 +82,7 @@ func getGATrackingID(cr *argoprojv1a1.ArgoCD) string { } // getHelpChatURL will return the help chat URL for the given Argo CD. -func getHelpChatURL(cr *argoprojv1a1.ArgoCD) string { +func getHelpChatURL(cr *argoproj.ArgoCD) string { url := common.ArgoCDDefaultHelpChatURL if len(cr.Spec.HelpChatURL) > 0 { url = cr.Spec.HelpChatURL @@ -92,7 +91,7 @@ func getHelpChatURL(cr *argoprojv1a1.ArgoCD) string { } // getHelpChatText will return the help chat text for the given Argo CD. -func getHelpChatText(cr *argoprojv1a1.ArgoCD) string { +func getHelpChatText(cr *argoproj.ArgoCD) string { text := common.ArgoCDDefaultHelpChatText if len(cr.Spec.HelpChatText) > 0 { text = cr.Spec.HelpChatText @@ -101,7 +100,7 @@ func getHelpChatText(cr *argoprojv1a1.ArgoCD) string { } // getKustomizeBuildOptions will return the kuztomize build options for the given ArgoCD. -func getKustomizeBuildOptions(cr *argoprojv1a1.ArgoCD) string { +func getKustomizeBuildOptions(cr *argoproj.ArgoCD) string { kbo := common.ArgoCDDefaultKustomizeBuildOptions if len(cr.Spec.KustomizeBuildOptions) > 0 { kbo = cr.Spec.KustomizeBuildOptions @@ -110,7 +109,7 @@ func getKustomizeBuildOptions(cr *argoprojv1a1.ArgoCD) string { } // getOIDCConfig will return the OIDC configuration for the given ArgoCD. -func getOIDCConfig(cr *argoprojv1a1.ArgoCD) string { +func getOIDCConfig(cr *argoproj.ArgoCD) string { config := common.ArgoCDDefaultOIDCConfig if len(cr.Spec.OIDCConfig) > 0 { config = cr.Spec.OIDCConfig @@ -119,7 +118,7 @@ func getOIDCConfig(cr *argoprojv1a1.ArgoCD) string { } // getRBACPolicy will return the RBAC policy for the given ArgoCD. -func getRBACPolicy(cr *argoprojv1a1.ArgoCD) string { +func getRBACPolicy(cr *argoproj.ArgoCD) string { policy := common.ArgoCDDefaultRBACPolicy if cr.Spec.RBAC.Policy != nil { policy = *cr.Spec.RBAC.Policy @@ -128,7 +127,7 @@ func getRBACPolicy(cr *argoprojv1a1.ArgoCD) string { } // getRBACDefaultPolicy will retun the RBAC default policy for the given ArgoCD. -func getRBACDefaultPolicy(cr *argoprojv1a1.ArgoCD) string { +func getRBACDefaultPolicy(cr *argoproj.ArgoCD) string { dp := common.ArgoCDDefaultRBACDefaultPolicy if cr.Spec.RBAC.DefaultPolicy != nil { dp = *cr.Spec.RBAC.DefaultPolicy @@ -137,7 +136,7 @@ func getRBACDefaultPolicy(cr *argoprojv1a1.ArgoCD) string { } // getRBACScopes will return the RBAC scopes for the given ArgoCD. -func getRBACScopes(cr *argoprojv1a1.ArgoCD) string { +func getRBACScopes(cr *argoproj.ArgoCD) string { scopes := common.ArgoCDDefaultRBACScopes if cr.Spec.RBAC.Scopes != nil { scopes = *cr.Spec.RBAC.Scopes @@ -146,7 +145,7 @@ func getRBACScopes(cr *argoprojv1a1.ArgoCD) string { } // getResourceCustomizations loads Resource Customizations from argocd-cm ConfigMap -func getResourceCustomizations(cr *argoprojv1a1.ArgoCD) string { +func getResourceCustomizations(cr *argoproj.ArgoCD) string { rc := common.ArgoCDDefaultResourceCustomizations if cr.Spec.ResourceCustomizations != "" { rc = cr.Spec.ResourceCustomizations @@ -156,7 +155,7 @@ func getResourceCustomizations(cr *argoprojv1a1.ArgoCD) string { } // getResourceHealthChecks loads health customizations to `resource.customizations.health` from argocd-cm ConfigMap -func getResourceHealthChecks(cr *argoprojv1a1.ArgoCD) map[string]string { +func getResourceHealthChecks(cr *argoproj.ArgoCD) map[string]string { healthCheck := make(map[string]string) if cr.Spec.ResourceHealthChecks != nil { resourceHealthChecks := cr.Spec.ResourceHealthChecks @@ -170,11 +169,11 @@ func getResourceHealthChecks(cr *argoprojv1a1.ArgoCD) map[string]string { } // getResourceIgnoreDifferences loads ignore differences customizations to `resource.customizations.ignoreDifferences` from argocd-cm ConfigMap -func getResourceIgnoreDifferences(cr *argoprojv1a1.ArgoCD) (map[string]string, error) { +func getResourceIgnoreDifferences(cr *argoproj.ArgoCD) (map[string]string, error) { ignoreDiff := make(map[string]string) if cr.Spec.ResourceIgnoreDifferences != nil { resourceIgnoreDiff := cr.Spec.ResourceIgnoreDifferences - if !reflect.DeepEqual(resourceIgnoreDiff.All, &v1alpha1.IgnoreDifferenceCustomization{}) { + if !reflect.DeepEqual(resourceIgnoreDiff.All, &argoproj.IgnoreDifferenceCustomization{}) { subkey := "resource.customizations.ignoreDifferences.all" bytes, err := yaml.Marshal(resourceIgnoreDiff.All) if err != nil { @@ -197,7 +196,7 @@ func getResourceIgnoreDifferences(cr *argoprojv1a1.ArgoCD) (map[string]string, e } // getResourceActions loads custom actions to `resource.customizations.actions` from argocd-cm ConfigMap -func getResourceActions(cr *argoprojv1a1.ArgoCD) map[string]string { +func getResourceActions(cr *argoproj.ArgoCD) map[string]string { action := make(map[string]string) if cr.Spec.ResourceActions != nil { resourceAction := cr.Spec.ResourceActions @@ -211,7 +210,7 @@ func getResourceActions(cr *argoprojv1a1.ArgoCD) map[string]string { } // getResourceExclusions will return the resource exclusions for the given ArgoCD. -func getResourceExclusions(cr *argoprojv1a1.ArgoCD) string { +func getResourceExclusions(cr *argoproj.ArgoCD) string { re := common.ArgoCDDefaultResourceExclusions if cr.Spec.ResourceExclusions != "" { re = cr.Spec.ResourceExclusions @@ -220,7 +219,7 @@ func getResourceExclusions(cr *argoprojv1a1.ArgoCD) string { } // getResourceInclusions will return the resource inclusions for the given ArgoCD. -func getResourceInclusions(cr *argoprojv1a1.ArgoCD) string { +func getResourceInclusions(cr *argoproj.ArgoCD) string { re := common.ArgoCDDefaultResourceInclusions if cr.Spec.ResourceInclusions != "" { re = cr.Spec.ResourceInclusions @@ -229,9 +228,9 @@ func getResourceInclusions(cr *argoprojv1a1.ArgoCD) string { } // getResourceTrackingMethod will return the resource tracking method for the given ArgoCD. -func getResourceTrackingMethod(cr *argoprojv1a1.ArgoCD) string { - rtm := argoprojv1a1.ParseResourceTrackingMethod(cr.Spec.ResourceTrackingMethod) - if rtm == argoprojv1a1.ResourceTrackingMethodInvalid { +func getResourceTrackingMethod(cr *argoproj.ArgoCD) string { + rtm := argoproj.ParseResourceTrackingMethod(cr.Spec.ResourceTrackingMethod) + if rtm == argoproj.ResourceTrackingMethodInvalid { log.Info(fmt.Sprintf("Found '%s' as resource tracking method, which is invalid. Using default 'label' method.", cr.Spec.ResourceTrackingMethod)) } else if cr.Spec.ResourceTrackingMethod != "" { log.Info(fmt.Sprintf("Found '%s' as tracking method", cr.Spec.ResourceTrackingMethod)) @@ -242,7 +241,7 @@ func getResourceTrackingMethod(cr *argoprojv1a1.ArgoCD) string { } // getInitialRepositories will return the initial repositories for the given ArgoCD. -func getInitialRepositories(cr *argoprojv1a1.ArgoCD) string { +func getInitialRepositories(cr *argoproj.ArgoCD) string { repos := common.ArgoCDDefaultRepositories if len(cr.Spec.InitialRepositories) > 0 { repos = cr.Spec.InitialRepositories @@ -251,7 +250,7 @@ func getInitialRepositories(cr *argoprojv1a1.ArgoCD) string { } // getRepositoryCredentials will return the repository credentials for the given ArgoCD. -func getRepositoryCredentials(cr *argoprojv1a1.ArgoCD) string { +func getRepositoryCredentials(cr *argoproj.ArgoCD) string { repos := common.ArgoCDDefaultRepositoryCredentials if len(cr.Spec.RepositoryCredentials) > 0 { repos = cr.Spec.RepositoryCredentials @@ -260,7 +259,7 @@ func getRepositoryCredentials(cr *argoprojv1a1.ArgoCD) string { } // getSSHKnownHosts will return the SSH Known Hosts data for the given ArgoCD. -func getInitialSSHKnownHosts(cr *argoprojv1a1.ArgoCD) string { +func getInitialSSHKnownHosts(cr *argoproj.ArgoCD) string { skh := common.ArgoCDDefaultSSHKnownHosts if cr.Spec.InitialSSHKnownHosts.ExcludeDefaultHosts { skh = "" @@ -272,7 +271,7 @@ func getInitialSSHKnownHosts(cr *argoprojv1a1.ArgoCD) string { } // getTLSCerts will return the TLS certs for the given ArgoCD. -func getInitialTLSCerts(cr *argoprojv1a1.ArgoCD) map[string]string { +func getInitialTLSCerts(cr *argoproj.ArgoCD) map[string]string { certs := make(map[string]string) if len(cr.Spec.TLS.InitialCerts) > 0 { certs = cr.Spec.TLS.InitialCerts @@ -281,7 +280,7 @@ func getInitialTLSCerts(cr *argoprojv1a1.ArgoCD) map[string]string { } // newConfigMap returns a new ConfigMap instance for the given ArgoCD. -func newConfigMap(cr *argoprojv1a1.ArgoCD) *corev1.ConfigMap { +func newConfigMap(cr *argoproj.ArgoCD) *corev1.ConfigMap { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -292,7 +291,7 @@ func newConfigMap(cr *argoprojv1a1.ArgoCD) *corev1.ConfigMap { } // newConfigMapWithName creates a new ConfigMap with the given name for the given ArgCD. -func newConfigMapWithName(name string, cr *argoprojv1a1.ArgoCD) *corev1.ConfigMap { +func newConfigMapWithName(name string, cr *argoproj.ArgoCD) *corev1.ConfigMap { cm := newConfigMap(cr) cm.ObjectMeta.Name = name @@ -305,12 +304,12 @@ func newConfigMapWithName(name string, cr *argoprojv1a1.ArgoCD) *corev1.ConfigMa // newConfigMapWithName creates a new ConfigMap with the given suffix appended to the name. // The name for the CongifMap is based on the name of the given ArgCD. -func newConfigMapWithSuffix(suffix string, cr *argoprojv1a1.ArgoCD) *corev1.ConfigMap { +func newConfigMapWithSuffix(suffix string, cr *argoproj.ArgoCD) *corev1.ConfigMap { return newConfigMapWithName(fmt.Sprintf("%s-%s", cr.ObjectMeta.Name, suffix), cr) } // reconcileConfigMaps will ensure that all ArgoCD ConfigMaps are present. -func (r *ReconcileArgoCD) reconcileConfigMaps(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileConfigMaps(cr *argoproj.ArgoCD, useTLSForRedis bool) error { if err := r.reconcileArgoConfigMap(cr); err != nil { return err } @@ -344,7 +343,7 @@ func (r *ReconcileArgoCD) reconcileConfigMaps(cr *argoprojv1a1.ArgoCD, useTLSFor // reconcileCAConfigMap will ensure that the Certificate Authority ConfigMap is present. // This ConfigMap holds the CA Certificate data for client use. -func (r *ReconcileArgoCD) reconcileCAConfigMap(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileCAConfigMap(cr *argoproj.ArgoCD) error { cm := newConfigMapWithName(getCAConfigMapName(cr), cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { return nil // ConfigMap found, do nothing @@ -367,7 +366,7 @@ func (r *ReconcileArgoCD) reconcileCAConfigMap(cr *argoprojv1a1.ArgoCD) error { } // reconcileConfiguration will ensure that the main ConfigMap for ArgoCD is present. -func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoproj.ArgoCD) error { cm := newConfigMapWithName(common.ArgoCDConfigMapName, cr) cm.Data = make(map[string]string) @@ -482,7 +481,7 @@ func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoprojv1a1.ArgoCD) error if err := r.reconcileDexConfiguration(existingCM, cr); err != nil { return err } - } else if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == v1alpha1.SSOProviderTypeKeycloak { + } else if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeKeycloak { // retain oidc.config during reconcilliation when keycloak is configured cm.Data[common.ArgoCDKeyOIDCConfig] = existingCM.Data[common.ArgoCDKeyOIDCConfig] } @@ -498,7 +497,7 @@ func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoprojv1a1.ArgoCD) error } // reconcileGrafanaConfiguration will ensure that the Grafana configuration ConfigMap is present. -func (r *ReconcileArgoCD) reconcileGrafanaConfiguration(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaConfiguration(cr *argoproj.ArgoCD) error { if !cr.Spec.Grafana.Enabled { return nil // Grafana not enabled, do nothing. } @@ -544,7 +543,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaConfiguration(cr *argoprojv1a1.ArgoCD) } // reconcileGrafanaDashboards will ensure that the Grafana dashboards ConfigMap is present. -func (r *ReconcileArgoCD) reconcileGrafanaDashboards(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaDashboards(cr *argoproj.ArgoCD) error { if !cr.Spec.Grafana.Enabled { return nil // Grafana not enabled, do nothing. } @@ -580,7 +579,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaDashboards(cr *argoprojv1a1.ArgoCD) er } // reconcileRBAC will ensure that the ArgoCD RBAC ConfigMap is present. -func (r *ReconcileArgoCD) reconcileRBAC(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRBAC(cr *argoproj.ArgoCD) error { cm := newConfigMapWithName(common.ArgoCDRBACConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { return r.reconcileRBACConfigMap(cm, cr) @@ -589,7 +588,7 @@ func (r *ReconcileArgoCD) reconcileRBAC(cr *argoprojv1a1.ArgoCD) error { } // reconcileRBACConfigMap will ensure that the RBAC ConfigMap is syncronized with the given ArgoCD. -func (r *ReconcileArgoCD) reconcileRBACConfigMap(cm *corev1.ConfigMap, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRBACConfigMap(cm *corev1.ConfigMap, cr *argoproj.ArgoCD) error { changed := false // Policy CSV if cr.Spec.RBAC.Policy != nil && cm.Data[common.ArgoCDKeyRBACPolicyCSV] != *cr.Spec.RBAC.Policy { @@ -623,7 +622,7 @@ func (r *ReconcileArgoCD) reconcileRBACConfigMap(cm *corev1.ConfigMap, cr *argop } // reconcileRedisConfiguration will ensure that all of the Redis ConfigMaps are present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileRedisConfiguration(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileRedisConfiguration(cr *argoproj.ArgoCD, useTLSForRedis bool) error { if err := r.reconcileRedisHAConfigMap(cr, useTLSForRedis); err != nil { return err } @@ -634,7 +633,7 @@ func (r *ReconcileArgoCD) reconcileRedisConfiguration(cr *argoprojv1a1.ArgoCD, u } // reconcileRedisHAConfigMap will ensure that the Redis HA Health ConfigMap is present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileRedisHAHealthConfigMap(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileRedisHAHealthConfigMap(cr *argoproj.ArgoCD, useTLSForRedis bool) error { cm := newConfigMapWithName(common.ArgoCDRedisHAHealthConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { if !cr.Spec.HA.Enabled { @@ -661,7 +660,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAHealthConfigMap(cr *argoprojv1a1.ArgoC } // reconcileRedisHAConfigMap will ensure that the Redis HA ConfigMap is present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileRedisHAConfigMap(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileRedisHAConfigMap(cr *argoproj.ArgoCD, useTLSForRedis bool) error { cm := newConfigMapWithName(common.ArgoCDRedisHAConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { if !cr.Spec.HA.Enabled { @@ -689,7 +688,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAConfigMap(cr *argoprojv1a1.ArgoCD, use return r.Client.Create(context.TODO(), cm) } -func (r *ReconcileArgoCD) recreateRedisHAConfigMap(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) recreateRedisHAConfigMap(cr *argoproj.ArgoCD, useTLSForRedis bool) error { cm := newConfigMapWithName(common.ArgoCDRedisHAConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { if err := r.Client.Delete(context.TODO(), cm); err != nil { @@ -699,7 +698,7 @@ func (r *ReconcileArgoCD) recreateRedisHAConfigMap(cr *argoprojv1a1.ArgoCD, useT return r.reconcileRedisHAConfigMap(cr, useTLSForRedis) } -func (r *ReconcileArgoCD) recreateRedisHAHealthConfigMap(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) recreateRedisHAHealthConfigMap(cr *argoproj.ArgoCD, useTLSForRedis bool) error { cm := newConfigMapWithName(common.ArgoCDRedisHAHealthConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { if err := r.Client.Delete(context.TODO(), cm); err != nil { @@ -710,7 +709,7 @@ func (r *ReconcileArgoCD) recreateRedisHAHealthConfigMap(cr *argoprojv1a1.ArgoCD } // reconcileSSHKnownHosts will ensure that the ArgoCD SSH Known Hosts ConfigMap is present. -func (r *ReconcileArgoCD) reconcileSSHKnownHosts(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileSSHKnownHosts(cr *argoproj.ArgoCD) error { cm := newConfigMapWithName(common.ArgoCDKnownHostsConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { return nil // ConfigMap found, move along... @@ -727,7 +726,7 @@ func (r *ReconcileArgoCD) reconcileSSHKnownHosts(cr *argoprojv1a1.ArgoCD) error } // reconcileTLSCerts will ensure that the ArgoCD TLS Certs ConfigMap is present. -func (r *ReconcileArgoCD) reconcileTLSCerts(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileTLSCerts(cr *argoproj.ArgoCD) error { cm := newConfigMapWithName(common.ArgoCDTLSCertsConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { return nil // ConfigMap found, move along... @@ -742,7 +741,7 @@ func (r *ReconcileArgoCD) reconcileTLSCerts(cr *argoprojv1a1.ArgoCD) error { } // reconcileGPGKeysConfigMap creates a gpg-keys config map -func (r *ReconcileArgoCD) reconcileGPGKeysConfigMap(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGPGKeysConfigMap(cr *argoproj.ArgoCD) error { cm := newConfigMapWithName(common.ArgoCDGPGKeysConfigMapName, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, cm.Name, cm) { return nil diff --git a/controllers/argocd/configmap_test.go b/controllers/argocd/configmap_test.go index 70a3cb82d..bf2ed30f8 100644 --- a/controllers/argocd/configmap_test.go +++ b/controllers/argocd/configmap_test.go @@ -29,8 +29,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -127,7 +126,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap(t *testing.T) { defaultConfigMapData := map[string]string{ "application.instanceLabelKey": common.ArgoCDDefaultApplicationInstanceLabelKey, - "application.resourceTrackingMethod": argoprojv1alpha1.ResourceTrackingMethodLabel.String(), + "application.resourceTrackingMethod": argoproj.ResourceTrackingMethodLabel.String(), "admin.enabled": "true", "configManagementPlugins": "", "dex.config": "", @@ -158,8 +157,8 @@ func TestReconcileArgoCD_reconcileArgoConfigMap(t *testing.T) { }, { "with-banner", - []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { - a.Spec.Banner = &argoprojv1alpha1.Banner{ + []argoCDOpt{func(a *argoproj.ArgoCD) { + a.Spec.Banner = &argoproj.Banner{ Content: "Custom Styles - Banners", } }}, @@ -170,8 +169,8 @@ func TestReconcileArgoCD_reconcileArgoConfigMap(t *testing.T) { }, { "with-banner-and-url", - []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { - a.Spec.Banner = &argoprojv1alpha1.Banner{ + []argoCDOpt{func(a *argoproj.ArgoCD) { + a.Spec.Banner = &argoproj.Banner{ Content: "Custom Styles - Banners", URL: "https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/#banners", } @@ -185,8 +184,8 @@ func TestReconcileArgoCD_reconcileArgoConfigMap(t *testing.T) { for _, tt := range cmdTests { a := makeTestArgoCD(tt.opts...) - a.Spec.SSO = &argoprojv1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, } r := makeTestReconciler(t, a) @@ -275,7 +274,7 @@ func TestReconcileArgoCDCM_withRepoCredentials(t *testing.T) { func TestReconcileArgoCD_reconcileArgoConfigMap_withDisableAdmin(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.DisableAdmin = true }) r := makeTestReconciler(t, a) @@ -300,14 +299,14 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withDexConnector(t *testing.T) { tests := []struct { name string - updateCrSpecFunc func(cr *argoprojv1alpha1.ArgoCD) + updateCrSpecFunc func(cr *argoproj.ArgoCD) }{ { name: "dex config using .spec.sso.provider=dex + .spec.sso.dex", - updateCrSpecFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + updateCrSpecFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -325,10 +324,10 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withDexConnector(t *testing.T) { }}, } - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { - a.Spec.SSO = &argoprojv1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: false, }, } @@ -376,19 +375,19 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withDexDisabled(t *testing.T) { tests := []struct { name string - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD }{ { name: "dex disabled by removing .spec.sso", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }), }, { name: "dex disabled by switching provider", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), }, @@ -421,19 +420,19 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_dexConfigDeletedwhenDexDisabled( tests := []struct { name string - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) - argoCD *argoprojv1alpha1.ArgoCD + updateCrFunc func(cr *argoproj.ArgoCD) + argoCD *argoproj.ArgoCD wantConfigRemoved bool }{ { name: "dex disabled by removing .spec.sso.provider", - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Config: "test-dex-config", }, } @@ -442,15 +441,15 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_dexConfigDeletedwhenDexDisabled( }, { name: "dex disabled by switching provider", - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeKeycloak, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -510,12 +509,12 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_dexConfigDeletedwhenDexDisabled( func TestReconcileArgoCD_reconcileArgoConfigMap_withKustomizeVersions(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { - kv := argoprojv1alpha1.KustomizeVersionSpec{ + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { + kv := argoproj.KustomizeVersionSpec{ Version: "v4.1.0", Path: "/path/to/kustomize-4.1", } - var kvs []argoprojv1alpha1.KustomizeVersionSpec + var kvs []argoproj.KustomizeVersionSpec kvs = append(kvs, kv) a.Spec.KustomizeVersions = kvs }) @@ -538,7 +537,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withKustomizeVersions(t *testing func TestReconcileArgoCD_reconcileGPGKeysConfigMap(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.DisableAdmin = true }) r := makeTestReconciler(t, a) @@ -573,7 +572,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *te assert.NoError(t, err) rtm, ok := cm.Data[common.ArgoCDKeyResourceTrackingMethod] - assert.Equal(t, argoprojv1alpha1.ResourceTrackingMethodLabel.String(), rtm) + assert.Equal(t, argoproj.ResourceTrackingMethodLabel.String(), rtm) assert.True(t, ok) }) @@ -585,12 +584,12 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *te assert.NoError(t, err) rtm, ok := cm.Data[common.ArgoCDKeyResourceTrackingMethod] - assert.Equal(t, argoprojv1alpha1.ResourceTrackingMethodLabel.String(), rtm) + assert.Equal(t, argoproj.ResourceTrackingMethodLabel.String(), rtm) assert.True(t, ok) }) t.Run("Set tracking method to annotation+label", func(t *testing.T) { - a.Spec.ResourceTrackingMethod = argoprojv1alpha1.ResourceTrackingMethodAnnotationAndLabel.String() + a.Spec.ResourceTrackingMethod = argoproj.ResourceTrackingMethodAnnotationAndLabel.String() err = r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -602,11 +601,11 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *te rtm, ok := cm.Data[common.ArgoCDKeyResourceTrackingMethod] assert.True(t, ok) - assert.Equal(t, argoprojv1alpha1.ResourceTrackingMethodAnnotationAndLabel.String(), rtm) + assert.Equal(t, argoproj.ResourceTrackingMethodAnnotationAndLabel.String(), rtm) }) t.Run("Set tracking method to annotation", func(t *testing.T) { - a.Spec.ResourceTrackingMethod = argoprojv1alpha1.ResourceTrackingMethodAnnotation.String() + a.Spec.ResourceTrackingMethod = argoproj.ResourceTrackingMethodAnnotation.String() err = r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -618,7 +617,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *te rtm, ok := cm.Data[common.ArgoCDKeyResourceTrackingMethod] assert.True(t, ok) - assert.Equal(t, argoprojv1alpha1.ResourceTrackingMethodAnnotation.String(), rtm) + assert.Equal(t, argoproj.ResourceTrackingMethodAnnotation.String(), rtm) }) // Invalid value sets the default "label" @@ -635,7 +634,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *te rtm, ok := cm.Data[common.ArgoCDKeyResourceTrackingMethod] assert.True(t, ok) - assert.Equal(t, argoprojv1alpha1.ResourceTrackingMethodLabel.String(), rtm) + assert.Equal(t, argoproj.ResourceTrackingMethodLabel.String(), rtm) }) } @@ -645,7 +644,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceInclusions(t *testin customizations := "testing: testing" updatedCustomizations := "updated-testing: updated-testing" - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.ResourceInclusions = customizations }) r := makeTestReconciler(t, a) @@ -683,7 +682,7 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceInclusions(t *testin func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceCustomizations(t *testing.T) { logf.SetLogger(ZapLogger(true)) customizations := "testing: testing" - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.ResourceCustomizations = customizations }) r := makeTestReconciler(t, a) @@ -718,7 +717,7 @@ managedfieldsmanagers: - b ` - health := []argoprojv1alpha1.ResourceHealthCheck{ + health := []argoproj.ResourceHealthCheck{ { Group: "healthFoo", Kind: "healthFoo", @@ -730,7 +729,7 @@ managedfieldsmanagers: Check: "healthBar", }, } - actions := []argoprojv1alpha1.ResourceAction{ + actions := []argoproj.ResourceAction{ { Group: "actionsFoo", Kind: "actionsFoo", @@ -742,17 +741,17 @@ managedfieldsmanagers: Action: "actionsBar", }, } - ignoreDifferences := argoprojv1alpha1.ResourceIgnoreDifference{ - All: &v1alpha1.IgnoreDifferenceCustomization{ + ignoreDifferences := argoproj.ResourceIgnoreDifference{ + All: &argoproj.IgnoreDifferenceCustomization{ JqPathExpressions: []string{"a", "b"}, JsonPointers: []string{"a", "b"}, ManagedFieldsManagers: []string{"a", "b"}, }, - ResourceIdentifiers: []argoprojv1alpha1.ResourceIdentifiers{ + ResourceIdentifiers: []argoproj.ResourceIdentifiers{ { Group: "ignoreDiffBar", Kind: "ignoreDiffBar", - Customization: v1alpha1.IgnoreDifferenceCustomization{ + Customization: argoproj.IgnoreDifferenceCustomization{ JqPathExpressions: []string{"a", "b"}, JsonPointers: []string{"a", "b"}, ManagedFieldsManagers: []string{"a", "b"}, @@ -761,7 +760,7 @@ managedfieldsmanagers: }, } - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.ResourceHealthChecks = health a.Spec.ResourceActions = actions a.Spec.ResourceIgnoreDifferences = &ignoreDifferences @@ -806,12 +805,12 @@ func TestReconcile_emitEventOnDeprecatedResourceCustomizations(t *testing.T) { tests := []struct { name string - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantEvents []*corev1.Event }{ { name: "ResourceCustomizations used", - argoCD: makeTestArgoCD(func(ac *argoprojv1alpha1.ArgoCD) { + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { ac.Spec.ResourceCustomizations = "testing: testing" }), wantEvents: []*corev1.Event{resourceCustomizationsEvent}, diff --git a/controllers/argocd/custommapper.go b/controllers/argocd/custommapper.go index d1c11a949..502373571 100644 --- a/controllers/argocd/custommapper.go +++ b/controllers/argocd/custommapper.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" corev1 "k8s.io/api/core/v1" @@ -132,7 +132,7 @@ func (r *ReconcileArgoCD) namespaceResourceMapper(o client.Object) []reconcile.R labels := o.GetLabels() if v, ok := labels[common.ArgoCDManagedByLabel]; ok { - argocds := &argoprojv1alpha1.ArgoCDList{} + argocds := &argoproj.ArgoCDList{} if err := r.Client.List(context.TODO(), argocds, &client.ListOptions{Namespace: v}); err != nil { return result } @@ -161,7 +161,7 @@ func (r *ReconcileArgoCD) clusterSecretResourceMapper(o client.Object) []reconci labels := o.GetLabels() if v, ok := labels[common.ArgoCDSecretTypeLabel]; ok && v == "cluster" { - argocds := &argoprojv1alpha1.ArgoCDList{} + argocds := &argoproj.ArgoCDList{} if err := r.Client.List(context.TODO(), argocds, &client.ListOptions{Namespace: o.GetNamespace()}); err != nil { return result } diff --git a/controllers/argocd/custommapper_test.go b/controllers/argocd/custommapper_test.go index 95d43e1c7..d33eeb455 100644 --- a/controllers/argocd/custommapper_test.go +++ b/controllers/argocd/custommapper_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" corev1 "k8s.io/api/core/v1" @@ -104,7 +104,7 @@ func TestReconcileArgoCD_clusterRoleBindingMapper(t *testing.T) { } func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { - argocd := &v1alpha1.ArgoCD{ + argocd := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd", Namespace: "argocd-operator", @@ -321,7 +321,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { } func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { - argocd := &v1alpha1.ArgoCD{ + argocd := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd", Namespace: "argocd-operator", diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go index 71c43d8c2..6b247c9c8 100644 --- a/controllers/argocd/deployment.go +++ b/controllers/argocd/deployment.go @@ -23,7 +23,8 @@ import ( "strings" "time" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" @@ -38,7 +39,7 @@ import ( // getArgoCDRepoServerReplicas will return the size value for the argocd-repo-server replica count if it // has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or // replicas value is < 0. -func getArgoCDRepoServerReplicas(cr *argoprojv1a1.ArgoCD) *int32 { +func getArgoCDRepoServerReplicas(cr *argoproj.ArgoCD) *int32 { if cr.Spec.Repo.Replicas != nil && *cr.Spec.Repo.Replicas >= 0 { return cr.Spec.Repo.Replicas } @@ -49,14 +50,14 @@ func getArgoCDRepoServerReplicas(cr *argoprojv1a1.ArgoCD) *int32 { // getArgoCDServerReplicas will return the size value for the argocd-server replica count if it // has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or // replicas value is < 0. If Autoscale is enabled, the value for replicas in the argocd CR will be ignored. -func getArgoCDServerReplicas(cr *argoprojv1a1.ArgoCD) *int32 { +func getArgoCDServerReplicas(cr *argoproj.ArgoCD) *int32 { if !cr.Spec.Server.Autoscale.Enabled && cr.Spec.Server.Replicas != nil && *cr.Spec.Server.Replicas >= 0 { return cr.Spec.Server.Replicas } return nil } -func (r *ReconcileArgoCD) getArgoCDExport(cr *argoprojv1a1.ArgoCD) *argoprojv1a1.ArgoCDExport { +func (r *ReconcileArgoCD) getArgoCDExport(cr *argoproj.ArgoCD) *argoprojv1alpha1.ArgoCDExport { if cr.Spec.Import == nil { return nil } @@ -66,14 +67,14 @@ func (r *ReconcileArgoCD) getArgoCDExport(cr *argoprojv1a1.ArgoCD) *argoprojv1a1 namespace = *cr.Spec.Import.Namespace } - export := &argoprojv1a1.ArgoCDExport{} + export := &argoprojv1alpha1.ArgoCDExport{} if argoutil.IsObjectFound(r.Client, namespace, cr.Spec.Import.Name, export) { return export } return nil } -func getArgoExportSecretName(export *argoprojv1a1.ArgoCDExport) string { +func getArgoExportSecretName(export *argoprojv1alpha1.ArgoCDExport) string { name := argoutil.NameWithSuffix(export.ObjectMeta, "export") if export.Spec.Storage != nil && len(export.Spec.Storage.SecretName) > 0 { name = export.Spec.Storage.SecretName @@ -81,14 +82,14 @@ func getArgoExportSecretName(export *argoprojv1a1.ArgoCDExport) string { return name } -func getArgoImportBackend(client client.Client, cr *argoprojv1a1.ArgoCD) string { +func getArgoImportBackend(client client.Client, cr *argoproj.ArgoCD) string { backend := common.ArgoCDExportStorageBackendLocal namespace := cr.ObjectMeta.Namespace if cr.Spec.Import != nil && cr.Spec.Import.Namespace != nil && len(*cr.Spec.Import.Namespace) > 0 { namespace = *cr.Spec.Import.Namespace } - export := &argoprojv1a1.ArgoCDExport{} + export := &argoprojv1alpha1.ArgoCDExport{} if argoutil.IsObjectFound(client, namespace, cr.Spec.Import.Name, export) { if export.Spec.Storage != nil && len(export.Spec.Storage.Backend) > 0 { backend = export.Spec.Storage.Backend @@ -98,7 +99,7 @@ func getArgoImportBackend(client client.Client, cr *argoprojv1a1.ArgoCD) string } // getArgoImportCommand will return the command for the ArgoCD import process. -func getArgoImportCommand(client client.Client, cr *argoprojv1a1.ArgoCD) []string { +func getArgoImportCommand(client client.Client, cr *argoproj.ArgoCD) []string { cmd := make([]string, 0) cmd = append(cmd, "uid_entrypoint.sh") cmd = append(cmd, "argocd-operator-util") @@ -107,7 +108,7 @@ func getArgoImportCommand(client client.Client, cr *argoprojv1a1.ArgoCD) []strin return cmd } -func getArgoImportContainerEnv(cr *argoprojv1a1.ArgoCDExport) []corev1.EnvVar { +func getArgoImportContainerEnv(cr *argoprojv1alpha1.ArgoCDExport) []corev1.EnvVar { env := make([]corev1.EnvVar, 0) switch cr.Spec.Storage.Backend { @@ -141,7 +142,7 @@ func getArgoImportContainerEnv(cr *argoprojv1a1.ArgoCDExport) []corev1.EnvVar { } // getArgoImportContainerImage will return the container image for the Argo CD import process. -func getArgoImportContainerImage(cr *argoprojv1a1.ArgoCDExport) string { +func getArgoImportContainerImage(cr *argoprojv1alpha1.ArgoCDExport) string { img := common.ArgoCDDefaultExportJobImage if len(cr.Spec.Image) > 0 { img = cr.Spec.Image @@ -173,7 +174,7 @@ func getArgoImportVolumeMounts() []corev1.VolumeMount { } // getArgoImportVolumes will return the Volumes for the given ArgoCDExport. -func getArgoImportVolumes(cr *argoprojv1a1.ArgoCDExport) []corev1.Volume { +func getArgoImportVolumes(cr *argoprojv1alpha1.ArgoCDExport) []corev1.Volume { volumes := make([]corev1.Volume, 0) if cr.Spec.Storage != nil && cr.Spec.Storage.Backend == common.ArgoCDExportStorageBackendLocal { @@ -225,7 +226,7 @@ func getArgoRedisArgs(useTLS bool) []string { } // getArgoRepoCommand will return the command for the ArgoCD Repo component. -func getArgoRepoCommand(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) []string { +func getArgoRepoCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { cmd := make([]string, 0) cmd = append(cmd, "uid_entrypoint.sh") @@ -272,7 +273,7 @@ func getArgoCmpServerInitCommand() []string { } // getArgoServerCommand will return the command for the ArgoCD server component. -func getArgoServerCommand(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) []string { +func getArgoServerCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { cmd := make([]string, 0) cmd = append(cmd, "argocd-server") @@ -341,17 +342,17 @@ func isMergable(extraArgs []string, cmd []string) error { } // getDexServerAddress will return the Dex server address. -func getDexServerAddress(cr *argoprojv1a1.ArgoCD) string { +func getDexServerAddress(cr *argoproj.ArgoCD) string { return fmt.Sprintf("https://%s", fqdnServiceRef("dex-server", common.ArgoCDDefaultDexHTTPPort, cr)) } // getRepoServerAddress will return the Argo CD repo server address. -func getRepoServerAddress(cr *argoprojv1a1.ArgoCD) string { +func getRepoServerAddress(cr *argoproj.ArgoCD) string { return fqdnServiceRef("repo-server", common.ArgoCDDefaultRepoServerPort, cr) } // newDeployment returns a new Deployment instance for the given ArgoCD. -func newDeployment(cr *argoprojv1a1.ArgoCD) *appsv1.Deployment { +func newDeployment(cr *argoproj.ArgoCD) *appsv1.Deployment { return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -362,7 +363,7 @@ func newDeployment(cr *argoprojv1a1.ArgoCD) *appsv1.Deployment { } // newDeploymentWithName returns a new Deployment instance for the given ArgoCD using the given name. -func newDeploymentWithName(name string, component string, cr *argoprojv1a1.ArgoCD) *appsv1.Deployment { +func newDeploymentWithName(name string, component string, cr *argoproj.ArgoCD) *appsv1.Deployment { deploy := newDeployment(cr) deploy.ObjectMeta.Name = name @@ -397,12 +398,12 @@ func newDeploymentWithName(name string, component string, cr *argoprojv1a1.ArgoC } // newDeploymentWithSuffix returns a new Deployment instance for the given ArgoCD using the given suffix. -func newDeploymentWithSuffix(suffix string, component string, cr *argoprojv1a1.ArgoCD) *appsv1.Deployment { +func newDeploymentWithSuffix(suffix string, component string, cr *argoproj.ArgoCD) *appsv1.Deployment { return newDeploymentWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), component, cr) } // reconcileDeployments will ensure that all Deployment resources are present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileDeployments(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileDeployments(cr *argoproj.ArgoCD, useTLSForRedis bool) error { if err := r.reconcileDexDeployment(cr); err != nil { log.Error(err, "error reconciling dex deployment") @@ -437,7 +438,7 @@ func (r *ReconcileArgoCD) reconcileDeployments(cr *argoprojv1a1.ArgoCD, useTLSFo } // reconcileGrafanaDeployment will ensure the Deployment resource is present for the ArgoCD Grafana component. -func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoproj.ArgoCD) error { deploy := newDeploymentWithSuffix("grafana", "grafana", cr) deploy.Spec.Replicas = getGrafanaReplicas(cr) AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) @@ -569,7 +570,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaDeployment(cr *argoprojv1a1.ArgoCD) er } // reconcileRedisDeployment will ensure the Deployment resource is present for the ArgoCD Redis component. -func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoprojv1a1.ArgoCD, useTLS bool) error { +func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoproj.ArgoCD, useTLS bool) error { deploy := newDeploymentWithSuffix("redis", "redis", cr) AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) @@ -669,7 +670,7 @@ func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoprojv1a1.ArgoCD, useT } // reconcileRedisHAProxyDeployment will ensure the Deployment resource is present for the Redis HA Proxy component. -func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoproj.ArgoCD) error { deploy := newDeploymentWithSuffix("redis-ha-haproxy", "redis", cr) deploy.Spec.Template.Spec.Affinity = &corev1.Affinity{ @@ -875,7 +876,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoprojv1a1.ArgoC } // reconcileRepoDeployment will ensure the Deployment resource is present for the ArgoCD Repo component. -func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) automountToken := false if cr.Spec.Repo.MountSAToken { @@ -1177,7 +1178,7 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoprojv1a1.ArgoCD, useTL } // reconcileServerDeployment will ensure the Deployment resource is present for the ArgoCD Server component. -func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { deploy := newDeploymentWithSuffix("server", "server", cr) serverEnv := cr.Spec.Server.Env serverEnv = argoutil.EnvMerge(serverEnv, proxyEnvVars(), false) diff --git a/controllers/argocd/deployment_test.go b/controllers/argocd/deployment_test.go index f557ac3c6..5c0ccecca 100644 --- a/controllers/argocd/deployment_test.go +++ b/controllers/argocd/deployment_test.go @@ -22,8 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) const ( @@ -61,7 +60,7 @@ func TestReconcileArgoCD_reconcileRepoDeployment_replicas(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.Replicas = &test.replicas }) r := makeTestReconciler(t, a) @@ -123,7 +122,7 @@ func TestReconcileArgoCD_reconcile_ServerDeployment_replicas(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Replicas = test.initialReplicas a.Spec.Server.Autoscale.Enabled = test.autoscale }) @@ -159,11 +158,11 @@ func TestReconcileArgoCD_reconcile_ServerDeployment_replicas(t *testing.T) { func TestReconcileArgoCD_reconcileRepoDeployment_loglevel(t *testing.T) { logf.SetLogger(ZapLogger(true)) - repoDeps := []*argoprojv1alpha1.ArgoCD{ - makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + repoDeps := []*argoproj.ArgoCD{ + makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.LogLevel = "warn" }), - makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.LogLevel = "error" }), makeTestArgoCD(), @@ -234,7 +233,7 @@ func TestReconcileArgoCD_reconcileRepoDeployment_volumes(t *testing.T) { } logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.Volumes = []corev1.Volume{customVolume} }) r := makeTestReconciler(t, a) @@ -407,7 +406,7 @@ func TestReconcileArgoCD_reconcileRepoDeployment_mounts(t *testing.T) { } logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.VolumeMounts = []corev1.VolumeMount{testMount} }) r := makeTestReconciler(t, a) @@ -427,7 +426,7 @@ func TestReconcileArgoCD_reconcileRepoDeployment_mounts(t *testing.T) { func TestReconcileArgoCD_reconcileRepoDeployment_initContainers(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { ic := corev1.Container{ Name: "test-init-container", Image: "test-image", @@ -555,11 +554,11 @@ func TestReconcileArgoCD_reconcileDeployments_proxy(t *testing.T) { t.Setenv("no_proxy", testNoProxy) logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Grafana.Enabled = true - a.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Config: "test", }, } @@ -584,11 +583,11 @@ func TestReconcileArgoCD_reconcileDeployments_proxy(t *testing.T) { func TestReconcileArgoCD_reconcileDeployments_proxy_update_existing(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Grafana.Enabled = true - a.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Config: "test", }, } @@ -627,7 +626,7 @@ func TestReconcileArgoCD_reconcileDeployments_HA_proxy(t *testing.T) { t.Setenv("no_proxy", testNoProxy) logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.HA.Enabled = true }) r := makeTestReconciler(t, a) @@ -644,7 +643,7 @@ func TestReconcileArgoCD_reconcileDeployments_HA_proxy_with_resources(t *testing t.Setenv("no_proxy", testNoProxy) logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCDWithResources(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCDWithResources(func(a *argoproj.ArgoCD) { a.Spec.HA.Enabled = true }) r := makeTestReconciler(t, a) @@ -780,8 +779,8 @@ func Test_proxyEnvVars(t *testing.T) { func TestReconcileArgoCD_reconcileDeployment_nodePlacement(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD((func(a *argoprojv1alpha1.ArgoCD) { - a.Spec.NodePlacement = &argoprojv1alpha1.ArgoCDNodePlacementSpec{ + a := makeTestArgoCD((func(a *argoproj.ArgoCD) { + a.Spec.NodePlacement = &argoproj.ArgoCDNodePlacementSpec{ NodeSelector: deploymentDefaultNodeSelector(), Tolerations: deploymentDefaultTolerations(), } @@ -861,7 +860,7 @@ func TestReconcileArgocd_reconcileRepoServerRedisTLS(t *testing.T) { t.Run("with DisableTLSVerification = true", func(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(cd *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(cd *argoproj.ArgoCD) { cd.Spec.Redis.DisableTLSVerification = true }) r := makeTestReconciler(t, a) @@ -1102,7 +1101,7 @@ func TestArgoCDServerCommand_isMergable(t *testing.T) { func TestReconcileArgoCD_reconcileServerDeploymentWithInsecure(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Insecure = true }) r := makeTestReconciler(t, a) @@ -1190,7 +1189,7 @@ func TestReconcileArgoCD_reconcileServerDeploymentChangedToInsecure(t *testing.T assert.NoError(t, r.reconcileServerDeployment(a, false)) - a = makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a = makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Insecure = true }) assert.NoError(t, r.reconcileServerDeployment(a, false)) @@ -1359,7 +1358,7 @@ func TestReconcileArgoCD_reconcileRedisDeployment_with_error(t *testing.T) { } func operationProcessors(n int32) argoCDOpt { - return func(a *argoprojv1alpha1.ArgoCD) { + return func(a *argoproj.ArgoCD) { a.Spec.Controller.Processors.Operation = n } } @@ -1424,7 +1423,7 @@ func Test_UpdateNodePlacement(t *testing.T) { } func parallelismLimit(n int32) argoCDOpt { - return func(a *argoprojv1alpha1.ArgoCD) { + return func(a *argoproj.ArgoCD) { a.Spec.Controller.ParallelismLimit = n } } @@ -1487,7 +1486,7 @@ func assertNotFound(t *testing.T, err error) { } func controllerProcessors(n int32) argoCDOpt { - return func(a *argoprojv1alpha1.ArgoCD) { + return func(a *argoproj.ArgoCD) { a.Spec.Controller.Processors.Status = n } } @@ -1672,7 +1671,7 @@ func TestReconcileArgoCD_reconcile_RepoServerChanges(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.MountSAToken = test.mountSAToken a.Spec.Repo.ServiceAccount = test.serviceAccount }) diff --git a/controllers/argocd/dex.go b/controllers/argocd/dex.go index 5ae952eb0..916b84aa3 100644 --- a/controllers/argocd/dex.go +++ b/controllers/argocd/dex.go @@ -17,8 +17,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -32,16 +31,16 @@ type DexConnector struct { } // UseDex determines whether Dex resources should be created and configured or not -func UseDex(cr *argoprojv1a1.ArgoCD) bool { +func UseDex(cr *argoproj.ArgoCD) bool { if cr.Spec.SSO != nil { - return cr.Spec.SSO.Provider.ToLower() == v1alpha1.SSOProviderTypeDex + return cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeDex } return false } // getDexOAuthClientSecret will return the OAuth client secret for the given ArgoCD. -func (r *ReconcileArgoCD) getDexOAuthClientSecret(cr *argoprojv1a1.ArgoCD) (*string, error) { +func (r *ReconcileArgoCD) getDexOAuthClientSecret(cr *argoproj.ArgoCD) (*string, error) { sa := newServiceAccountWithName(common.ArgoCDDefaultDexServiceAccountName, cr) if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { return nil, err @@ -98,7 +97,7 @@ func (r *ReconcileArgoCD) getDexOAuthClientSecret(cr *argoprojv1a1.ArgoCD) (*str } // reconcileDexConfiguration will ensure that Dex is configured properly. -func (r *ReconcileArgoCD) reconcileDexConfiguration(cm *corev1.ConfigMap, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileDexConfiguration(cm *corev1.ConfigMap, cr *argoproj.ArgoCD) error { actual := cm.Data[common.ArgoCDKeyDexConfig] desired := getDexConfig(cr) @@ -133,7 +132,7 @@ func (r *ReconcileArgoCD) reconcileDexConfiguration(cm *corev1.ConfigMap, cr *ar } // getOpenShiftDexConfig will return the configuration for the Dex server running on OpenShift. -func (r *ReconcileArgoCD) getOpenShiftDexConfig(cr *argoprojv1a1.ArgoCD) (string, error) { +func (r *ReconcileArgoCD) getOpenShiftDexConfig(cr *argoproj.ArgoCD) (string, error) { groups := []string{} @@ -167,7 +166,7 @@ func (r *ReconcileArgoCD) getOpenShiftDexConfig(cr *argoprojv1a1.ArgoCD) (string } // reconcileDexServiceAccount will ensure that the Dex ServiceAccount is configured properly for OpenShift OAuth. -func (r *ReconcileArgoCD) reconcileDexServiceAccount(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileDexServiceAccount(cr *argoproj.ArgoCD) error { // if openShiftOAuth set to false in `.spec.sso.dex`, no need to configure it if cr.Spec.SSO == nil || cr.Spec.SSO.Dex == nil || !cr.Spec.SSO.Dex.OpenShiftOAuth { @@ -203,7 +202,7 @@ func (r *ReconcileArgoCD) reconcileDexServiceAccount(cr *argoprojv1a1.ArgoCD) er } // reconcileDexDeployment will ensure the Deployment resource is present for the ArgoCD Dex component. -func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoproj.ArgoCD) error { deploy := newDeploymentWithSuffix("dex-server", "dex-server", cr) AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) @@ -352,7 +351,7 @@ func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoprojv1a1.ArgoCD) error } // reconcileDexService will ensure that the Service for Dex is present. -func (r *ReconcileArgoCD) reconcileDexService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileDexService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("dex-server", "dex-server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { @@ -397,7 +396,7 @@ func (r *ReconcileArgoCD) reconcileDexService(cr *argoprojv1a1.ArgoCD) error { // reconcileDexResources consolidates all dex resources reconciliation calls. It serves as the single place to trigger both creation // and deletion of dex resources based on the specified configuration of dex -func (r *ReconcileArgoCD) reconcileDexResources(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileDexResources(cr *argoproj.ArgoCD) error { if _, err := r.reconcileRole(common.ArgoCDDexServerComponent, policyRuleForDexServer(), cr); err != nil { log.Error(err, "error reconciling dex role") @@ -441,7 +440,7 @@ func (r *ReconcileArgoCD) reconcileDexResources(cr *argoprojv1a1.ArgoCD) error { // RoleBinding and deployment are dependent on these resouces. During deletion the order is reversed. // Deployment and RoleBinding must be deleted before the role and sa. deleteDexResources will only be called during // delete events, so we don't need to worry about duplicate, recurring reconciliation calls -func (r *ReconcileArgoCD) deleteDexResources(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) deleteDexResources(cr *argoproj.ArgoCD) error { sa := &corev1.ServiceAccount{} role := &rbacv1.Role{} diff --git a/controllers/argocd/dexUtil.go b/controllers/argocd/dexUtil.go index fee911fdd..98160990c 100644 --- a/controllers/argocd/dexUtil.go +++ b/controllers/argocd/dexUtil.go @@ -7,7 +7,7 @@ import ( corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -23,7 +23,7 @@ import ( // that if the spec is not configured. // 3. the default is configured in common.ArgoCDDefaultDexVersion and // common.ArgoCDDefaultDexImage. -func getDexContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getDexContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := "" @@ -53,18 +53,18 @@ func getDexContainerImage(cr *argoprojv1a1.ArgoCD) string { } // getDexOAuthRedirectURI will return the OAuth redirect URI for the Dex server. -func (r *ReconcileArgoCD) getDexOAuthRedirectURI(cr *argoprojv1a1.ArgoCD) string { +func (r *ReconcileArgoCD) getDexOAuthRedirectURI(cr *argoproj.ArgoCD) string { uri := r.getArgoServerURI(cr) return uri + common.ArgoCDDefaultDexOAuthRedirectPath } // getDexOAuthClientID will return the OAuth client ID for the given ArgoCD. -func getDexOAuthClientID(cr *argoprojv1a1.ArgoCD) string { +func getDexOAuthClientID(cr *argoproj.ArgoCD) string { return fmt.Sprintf("system:serviceaccount:%s:%s", cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDDefaultDexServiceAccountName)) } // getDexResources will return the ResourceRequirements for the Dex container. -func getDexResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getDexResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := v1.ResourceRequirements{} @@ -76,7 +76,7 @@ func getDexResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { return resources } -func getDexConfig(cr *argoprojv1a1.ArgoCD) string { +func getDexConfig(cr *argoproj.ArgoCD) string { config := common.ArgoCDDefaultDexConfig // Allow override of config from CR diff --git a/controllers/argocd/dex_test.go b/controllers/argocd/dex_test.go index 8eef4bcae..61e9f86a0 100644 --- a/controllers/argocd/dex_test.go +++ b/controllers/argocd/dex_test.go @@ -13,8 +13,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) @@ -24,21 +23,21 @@ func TestReconcileArgoCD_reconcileDexDeployment_with_dex_disabled(t *testing.T) tests := []struct { name string setEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD }{ { name: "dex disabled by not specifying .spec.sso.provider=dex", setEnvFunc: nil, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }), }, { name: "dex disabled by specifying different provider", setEnvFunc: nil, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), }, @@ -67,21 +66,21 @@ func TestReconcileArgoCD_reconcileDexDeployment_removes_dex_when_disabled(t *tes tests := []struct { name string setEnvFunc func(*testing.T, string) - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + updateCrFunc func(cr *argoproj.ArgoCD) updateEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantDeploymentDeleted bool }{ { name: "dex disabled by removing .spec.sso", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -91,15 +90,15 @@ func TestReconcileArgoCD_reconcileDexDeployment_removes_dex_when_disabled(t *tes { name: "dex disabled by switching provider", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -148,15 +147,15 @@ func TestReconcileArgoCD_reconcileDeployments_Dex_with_resources(t *testing.T) { tests := []struct { name string setEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD }{ { name: "dex with resources - .spec.sso.provider=dex", setEnvFunc: nil, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Resources: &corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceMemory: resourcev1.MustParse("128Mi"), @@ -210,8 +209,8 @@ func TestReconcileArgoCD_reconcileDeployments_Dex_with_resources(t *testing.T) { func TestReconcileArgoCD_reconcileDexDeployment(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - a.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, } r := makeTestReconciler(t, a) assert.NoError(t, r.reconcileDexDeployment(a)) @@ -404,28 +403,28 @@ func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) { tests := []struct { name string setEnvFunc func(*testing.T, string) - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) - argoCD *argoprojv1alpha1.ArgoCD + updateCrFunc func(cr *argoproj.ArgoCD) + argoCD *argoproj.ArgoCD wantPodSpec corev1.PodSpec }{ { name: "update dex deployment - .spec.sso.provider=dex + .spec.sso.dex", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.Image = "justatest" cr.Spec.Version = "latest" - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Image: "testdex", Version: "v0.0.1", }, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -471,21 +470,21 @@ func TestReconcileArgoCD_reconcileDexService_removes_dex_when_disabled(t *testin tests := []struct { name string setEnvFunc func(*testing.T, string) - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + updateCrFunc func(cr *argoproj.ArgoCD) updateEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantServiceDeleted bool }{ { name: "dex disabled by removing .spec.sso", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -495,15 +494,15 @@ func TestReconcileArgoCD_reconcileDexService_removes_dex_when_disabled(t *testin { name: "dex disabled by switching provider", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -553,21 +552,21 @@ func TestReconcileArgoCD_reconcileDexServiceAccount_removes_dex_when_disabled(t tests := []struct { name string setEnvFunc func(*testing.T, string) - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + updateCrFunc func(cr *argoproj.ArgoCD) updateEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantServiceAccountDeleted bool }{ { name: "dex disabled by removing .spec.sso", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -577,15 +576,15 @@ func TestReconcileArgoCD_reconcileDexServiceAccount_removes_dex_when_disabled(t { name: "dex disabled by switching provider", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -636,21 +635,21 @@ func TestReconcileArgoCD_reconcileRole_dex_disabled(t *testing.T) { tests := []struct { name string setEnvFunc func(*testing.T, string) - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + updateCrFunc func(cr *argoproj.ArgoCD) updateEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantRoleDeleted bool }{ { name: "dex disabled by removing .spec.sso", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -660,15 +659,15 @@ func TestReconcileArgoCD_reconcileRole_dex_disabled(t *testing.T) { { name: "dex disabled by switching provider", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -724,21 +723,21 @@ func TestReconcileArgoCD_reconcileRoleBinding_dex_disabled(t *testing.T) { tests := []struct { name string setEnvFunc func(*testing.T, string) - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + updateCrFunc func(cr *argoproj.ArgoCD) updateEnvFunc func(*testing.T, string) - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantRoleBindingDeleted bool }{ { name: "dex disabled by removing .spec.sso", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { + updateCrFunc: func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -748,15 +747,15 @@ func TestReconcileArgoCD_reconcileRoleBinding_dex_disabled(t *testing.T) { { name: "dex disabled by switching provider", setEnvFunc: nil, - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeKeycloak, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }, - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } diff --git a/controllers/argocd/grafana.go b/controllers/argocd/grafana.go index b2d460bb3..a6d12f08b 100644 --- a/controllers/argocd/grafana.go +++ b/controllers/argocd/grafana.go @@ -26,7 +26,7 @@ import ( "github.com/sethvargo/go-password/password" appsv1 "k8s.io/api/apps/v1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) @@ -60,7 +60,7 @@ func generateGrafanaSecretKey() ([]byte, error) { } // getGrafanaHost will return the hostname value for Grafana. -func getGrafanaHost(cr *argoprojv1a1.ArgoCD) string { +func getGrafanaHost(cr *argoproj.ArgoCD) string { host := nameWithSuffix("grafana", cr) if len(cr.Spec.Grafana.Host) > 0 { host = cr.Spec.Grafana.Host @@ -69,7 +69,7 @@ func getGrafanaHost(cr *argoprojv1a1.ArgoCD) string { } // getGrafanaReplicas will return the size value for the Grafana replica count. -func getGrafanaReplicas(cr *argoprojv1a1.ArgoCD) *int32 { +func getGrafanaReplicas(cr *argoproj.ArgoCD) *int32 { replicas := common.ArgoCDDefaultGrafanaReplicas if cr.Spec.Grafana.Size != nil { if *cr.Spec.Grafana.Size >= 0 && *cr.Spec.Grafana.Size != replicas { @@ -89,7 +89,7 @@ func getGrafanaConfigPath() string { } // hasGrafanaSpecChanged will return true if the supported properties differs in the actual versus the desired state. -func hasGrafanaSpecChanged(actual *appsv1.Deployment, desired *argoprojv1a1.ArgoCD) bool { +func hasGrafanaSpecChanged(actual *appsv1.Deployment, desired *argoproj.ArgoCD) bool { // Replica count if desired.Spec.Grafana.Size != nil { // Replica count specified in desired state if *desired.Spec.Grafana.Size >= 0 && *actual.Spec.Replicas != *desired.Spec.Grafana.Size { diff --git a/controllers/argocd/hooks.go b/controllers/argocd/hooks.go index 0f215012f..cd4d618d4 100644 --- a/controllers/argocd/hooks.go +++ b/controllers/argocd/hooks.go @@ -3,7 +3,7 @@ package argocd import ( "sync" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) var ( @@ -12,7 +12,7 @@ var ( ) // Hook changes resources as they are created or updated by the reconciler. -type Hook func(*argoprojv1alpha1.ArgoCD, interface{}, string) error +type Hook func(*argoproj.ArgoCD, interface{}, string) error // Register adds a modifier for updating resources during reconciliation. func Register(h ...Hook) { @@ -22,7 +22,7 @@ func Register(h ...Hook) { } // nolint:unparam -func applyReconcilerHook(cr *argoprojv1alpha1.ArgoCD, i interface{}, hint string) error { +func applyReconcilerHook(cr *argoproj.ArgoCD, i interface{}, hint string) error { mutex.Lock() defer mutex.Unlock() for _, v := range hooks { diff --git a/controllers/argocd/hooks_test.go b/controllers/argocd/hooks_test.go index fec70f5cd..c75f574fc 100644 --- a/controllers/argocd/hooks_test.go +++ b/controllers/argocd/hooks_test.go @@ -8,13 +8,13 @@ import ( appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/rbac/v1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) var errMsg = errors.New("this is a test error") -func testDeploymentHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) error { +func testDeploymentHook(cr *argoproj.ArgoCD, v interface{}, s string) error { switch o := v.(type) { case *appsv1.Deployment: var replicas int32 = 3 @@ -23,7 +23,7 @@ func testDeploymentHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) er return nil } -func testClusterRoleHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) error { +func testClusterRoleHook(cr *argoproj.ArgoCD, v interface{}, s string) error { switch o := v.(type) { case *v1.ClusterRole: o.Rules = append(o.Rules, policyRuleForApplicationController()...) @@ -31,7 +31,7 @@ func testClusterRoleHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) e return nil } -func testRoleHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) error { +func testRoleHook(cr *argoproj.ArgoCD, v interface{}, s string) error { switch o := v.(type) { case *v1.Role: if o.Name == cr.Name+"-"+common.ArgoCDApplicationControllerComponent { @@ -41,7 +41,7 @@ func testRoleHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) error { return nil } -func testErrorHook(cr *argoprojv1alpha1.ArgoCD, v interface{}, s string) error { +func testErrorHook(cr *argoproj.ArgoCD, v interface{}, s string) error { return errMsg } diff --git a/controllers/argocd/hpa.go b/controllers/argocd/hpa.go index 0cee4a3ca..f55e6324c 100644 --- a/controllers/argocd/hpa.go +++ b/controllers/argocd/hpa.go @@ -21,7 +21,7 @@ import ( autoscaling "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -32,7 +32,7 @@ var ( tcup int32 = 50 ) -func newHorizontalPodAutoscaler(cr *argoprojv1a1.ArgoCD) *autoscaling.HorizontalPodAutoscaler { +func newHorizontalPodAutoscaler(cr *argoproj.ArgoCD) *autoscaling.HorizontalPodAutoscaler { return &autoscaling.HorizontalPodAutoscaler{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -42,7 +42,7 @@ func newHorizontalPodAutoscaler(cr *argoprojv1a1.ArgoCD) *autoscaling.Horizontal } } -func newHorizontalPodAutoscalerWithName(name string, cr *argoprojv1a1.ArgoCD) *autoscaling.HorizontalPodAutoscaler { +func newHorizontalPodAutoscalerWithName(name string, cr *argoproj.ArgoCD) *autoscaling.HorizontalPodAutoscaler { hpa := newHorizontalPodAutoscaler(cr) hpa.ObjectMeta.Name = name @@ -53,12 +53,12 @@ func newHorizontalPodAutoscalerWithName(name string, cr *argoprojv1a1.ArgoCD) *a return hpa } -func newHorizontalPodAutoscalerWithSuffix(suffix string, cr *argoprojv1a1.ArgoCD) *autoscaling.HorizontalPodAutoscaler { +func newHorizontalPodAutoscalerWithSuffix(suffix string, cr *argoproj.ArgoCD) *autoscaling.HorizontalPodAutoscaler { return newHorizontalPodAutoscalerWithName(nameWithSuffix(suffix, cr), cr) } // reconcileServerHPA will ensure that the HorizontalPodAutoscaler is present for the Argo CD Server component, and reconcile any detected changes. -func (r *ReconcileArgoCD) reconcileServerHPA(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServerHPA(cr *argoproj.ArgoCD) error { defaultHPA := newHorizontalPodAutoscalerWithSuffix("server", cr) defaultHPA.Spec = autoscaling.HorizontalPodAutoscalerSpec{ @@ -108,7 +108,7 @@ func (r *ReconcileArgoCD) reconcileServerHPA(cr *argoprojv1a1.ArgoCD) error { } // reconcileAutoscalers will ensure that all HorizontalPodAutoscalers are present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileAutoscalers(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileAutoscalers(cr *argoproj.ArgoCD) error { if err := r.reconcileServerHPA(cr); err != nil { return err } diff --git a/controllers/argocd/ingress.go b/controllers/argocd/ingress.go index f28596b36..9d18c6c20 100644 --- a/controllers/argocd/ingress.go +++ b/controllers/argocd/ingress.go @@ -22,7 +22,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -37,7 +37,7 @@ func getPathOrDefault(path string) string { } // newIngress returns a new Ingress instance for the given ArgoCD. -func newIngress(cr *argoprojv1a1.ArgoCD) *networkingv1.Ingress { +func newIngress(cr *argoproj.ArgoCD) *networkingv1.Ingress { return &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -48,7 +48,7 @@ func newIngress(cr *argoprojv1a1.ArgoCD) *networkingv1.Ingress { } // newIngressWithName returns a new Ingress with the given name and ArgoCD. -func newIngressWithName(name string, cr *argoprojv1a1.ArgoCD) *networkingv1.Ingress { +func newIngressWithName(name string, cr *argoproj.ArgoCD) *networkingv1.Ingress { ingress := newIngress(cr) ingress.ObjectMeta.Name = name @@ -60,12 +60,12 @@ func newIngressWithName(name string, cr *argoprojv1a1.ArgoCD) *networkingv1.Ingr } // newIngressWithSuffix returns a new Ingress with the given name suffix for the ArgoCD. -func newIngressWithSuffix(suffix string, cr *argoprojv1a1.ArgoCD) *networkingv1.Ingress { +func newIngressWithSuffix(suffix string, cr *argoproj.ArgoCD) *networkingv1.Ingress { return newIngressWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), cr) } // reconcileIngresses will ensure that all ArgoCD Ingress resources are present. -func (r *ReconcileArgoCD) reconcileIngresses(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileIngresses(cr *argoproj.ArgoCD) error { if err := r.reconcileArgoServerIngress(cr); err != nil { return err } @@ -90,7 +90,7 @@ func (r *ReconcileArgoCD) reconcileIngresses(cr *argoprojv1a1.ArgoCD) error { } // reconcileArgoServerIngress will ensure that the ArgoCD Server Ingress is present. -func (r *ReconcileArgoCD) reconcileArgoServerIngress(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileArgoServerIngress(cr *argoproj.ArgoCD) error { ingress := newIngressWithSuffix("server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, ingress.Name, ingress) { if !cr.Spec.Server.Ingress.Enabled { @@ -166,7 +166,7 @@ func (r *ReconcileArgoCD) reconcileArgoServerIngress(cr *argoprojv1a1.ArgoCD) er } // reconcileArgoServerGRPCIngress will ensure that the ArgoCD Server GRPC Ingress is present. -func (r *ReconcileArgoCD) reconcileArgoServerGRPCIngress(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileArgoServerGRPCIngress(cr *argoproj.ArgoCD) error { ingress := newIngressWithSuffix("grpc", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, ingress.Name, ingress) { if !cr.Spec.Server.GRPC.Ingress.Enabled { @@ -241,7 +241,7 @@ func (r *ReconcileArgoCD) reconcileArgoServerGRPCIngress(cr *argoprojv1a1.ArgoCD } // reconcileGrafanaIngress will ensure that the ArgoCD Server GRPC Ingress is present. -func (r *ReconcileArgoCD) reconcileGrafanaIngress(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaIngress(cr *argoproj.ArgoCD) error { ingress := newIngressWithSuffix("grafana", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, ingress.Name, ingress) { if !cr.Spec.Grafana.Enabled || !cr.Spec.Grafana.Ingress.Enabled { @@ -318,7 +318,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaIngress(cr *argoprojv1a1.ArgoCD) error } // reconcilePrometheusIngress will ensure that the Prometheus Ingress is present. -func (r *ReconcileArgoCD) reconcilePrometheusIngress(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcilePrometheusIngress(cr *argoproj.ArgoCD) error { ingress := newIngressWithSuffix("prometheus", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, ingress.Name, ingress) { if !cr.Spec.Prometheus.Enabled || !cr.Spec.Prometheus.Ingress.Enabled { @@ -392,7 +392,7 @@ func (r *ReconcileArgoCD) reconcilePrometheusIngress(cr *argoprojv1a1.ArgoCD) er } // reconcileApplicationSetControllerIngress will ensure that the ApplicationSetController Ingress is present. -func (r *ReconcileArgoCD) reconcileApplicationSetControllerIngress(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileApplicationSetControllerIngress(cr *argoproj.ArgoCD) error { ingress := newIngressWithSuffix(common.ApplicationSetServiceNameSuffix, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, ingress.Name, ingress) { if cr.Spec.ApplicationSet == nil || !cr.Spec.ApplicationSet.WebhookServer.Ingress.Enabled { diff --git a/controllers/argocd/ingress_test.go b/controllers/argocd/ingress_test.go index ddf8e4f05..19f2bd8c8 100644 --- a/controllers/argocd/ingress_test.go +++ b/controllers/argocd/ingress_test.go @@ -9,8 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) @@ -36,7 +35,7 @@ func TestReconcileArgoCD_reconcile_ServerIngress_ingressClassName(t *testing.T) for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Ingress.Enabled = true a.Spec.Server.Ingress.IngressClassName = test.ingressClassName }) @@ -78,7 +77,7 @@ func TestReconcileArgoCD_reconcile_ServerGRPCIngress_ingressClassName(t *testing for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.GRPC.Ingress.Enabled = true a.Spec.Server.GRPC.Ingress.IngressClassName = test.ingressClassName }) @@ -120,7 +119,7 @@ func TestReconcileArgoCD_reconcile_GrafanaIngress_ingressClassName(t *testing.T) for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Grafana.Enabled = true a.Spec.Grafana.Ingress.Enabled = true a.Spec.Grafana.Ingress.IngressClassName = test.ingressClassName @@ -163,7 +162,7 @@ func TestReconcileArgoCD_reconcile_PrometheusIngress_ingressClassName(t *testing for _, test := range tests { t.Run(test.name, func(t *testing.T) { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Prometheus.Enabled = true a.Spec.Prometheus.Ingress.Enabled = true a.Spec.Prometheus.Ingress.IngressClassName = test.ingressClassName @@ -187,9 +186,9 @@ func TestReconcileArgoCD_reconcile_PrometheusIngress_ingressClassName(t *testing func TestReconcileApplicationSetService_Ingress(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - obj := v1alpha1.ArgoCDApplicationSet{ - WebhookServer: v1alpha1.WebhookServerSpec{ - Ingress: v1alpha1.ArgoCDIngressSpec{ + obj := argoproj.ArgoCDApplicationSet{ + WebhookServer: argoproj.WebhookServerSpec{ + Ingress: argoproj.ArgoCDIngressSpec{ Enabled: true, }, }, diff --git a/controllers/argocd/keycloak.go b/controllers/argocd/keycloak.go index 36d100cfa..0d91cd9c4 100644 --- a/controllers/argocd/keycloak.go +++ b/controllers/argocd/keycloak.go @@ -22,7 +22,7 @@ import ( "fmt" "os" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" @@ -164,7 +164,7 @@ type CustomKeycloakAPIRealm struct { // that if the spec is not configured. // 3. the default is configured in common.ArgoCDKeycloakVersion and // common.ArgoCDKeycloakImageName. -func getKeycloakContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getKeycloakContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := "" @@ -248,7 +248,7 @@ func defaultKeycloakResources() corev1.ResourceRequirements { } // getKeycloakResources will return the ResourceRequirements for the Keycloak container. -func getKeycloakResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getKeycloakResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { // Default values for Keycloak resources requirements. resources := defaultKeycloakResources() @@ -261,7 +261,7 @@ func getKeycloakResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { return resources } -func getKeycloakContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { +func getKeycloakContainer(cr *argoproj.ArgoCD) corev1.Container { envVars := []corev1.EnvVar{ {Name: "SSO_HOSTNAME", Value: "${SSO_HOSTNAME}"}, {Name: "DB_MIN_POOL_SIZE", Value: "${DB_MIN_POOL_SIZE}"}, @@ -334,7 +334,7 @@ func getKeycloakContainer(cr *argoprojv1a1.ArgoCD) corev1.Container { } } -func getKeycloakDeploymentConfigTemplate(cr *argoprojv1a1.ArgoCD) *appsv1.DeploymentConfig { +func getKeycloakDeploymentConfigTemplate(cr *argoproj.ArgoCD) *appsv1.DeploymentConfig { ns := cr.Namespace var medium corev1.StorageMedium = "Memory" keycloakContainer := getKeycloakContainer(cr) @@ -478,7 +478,7 @@ func getKeycloakRouteTemplate(ns string) *routev1.Route { } } -func newKeycloakTemplateInstance(cr *argoprojv1a1.ArgoCD) (*template.TemplateInstance, error) { +func newKeycloakTemplateInstance(cr *argoproj.ArgoCD) (*template.TemplateInstance, error) { tpl, err := newKeycloakTemplate(cr) if err != nil { return nil, err @@ -494,7 +494,7 @@ func newKeycloakTemplateInstance(cr *argoprojv1a1.ArgoCD) (*template.TemplateIns }, nil } -func newKeycloakTemplate(cr *argoprojv1a1.ArgoCD) (template.Template, error) { +func newKeycloakTemplate(cr *argoproj.ArgoCD) (template.Template, error) { ns := cr.Namespace tmpl := template.Template{} configMapTemplate := getKeycloakConfigMapTemplate(ns) @@ -575,7 +575,7 @@ func newKeycloakTemplate(cr *argoprojv1a1.ArgoCD) (template.Template, error) { return tmpl, err } -func newKeycloakIngress(cr *argoprojv1a1.ArgoCD) *networkingv1.Ingress { +func newKeycloakIngress(cr *argoproj.ArgoCD) *networkingv1.Ingress { pathType := networkingv1.PathTypeImplementationSpecific @@ -623,7 +623,7 @@ func newKeycloakIngress(cr *argoprojv1a1.ArgoCD) *networkingv1.Ingress { } } -func newKeycloakService(cr *argoprojv1a1.ArgoCD) *corev1.Service { +func newKeycloakService(cr *argoproj.ArgoCD) *corev1.Service { return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ @@ -653,7 +653,7 @@ func getKeycloakContainerEnv() []corev1.EnvVar { } } -func newKeycloakDeployment(cr *argoprojv1a1.ArgoCD) *k8sappsv1.Deployment { +func newKeycloakDeployment(cr *argoproj.ArgoCD) *k8sappsv1.Deployment { var replicas int32 = 1 return &k8sappsv1.Deployment{ @@ -706,7 +706,7 @@ func newKeycloakDeployment(cr *argoprojv1a1.ArgoCD) *k8sappsv1.Deployment { } } -func (r *ReconcileArgoCD) newKeycloakInstance(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) newKeycloakInstance(cr *argoproj.ArgoCD) error { // Create Keycloak Ingress ing := newKeycloakIngress(cr) @@ -769,7 +769,7 @@ func (r *ReconcileArgoCD) newKeycloakInstance(cr *argoprojv1a1.ArgoCD) error { } // prepares a keycloak config which is used in creating keycloak realm configuration. -func (r *ReconcileArgoCD) prepareKeycloakConfig(cr *argoprojv1a1.ArgoCD) (*keycloakConfig, error) { +func (r *ReconcileArgoCD) prepareKeycloakConfig(cr *argoproj.ArgoCD) (*keycloakConfig, error) { var tlsVerification bool // Get keycloak hostname from route. @@ -847,7 +847,7 @@ func (r *ReconcileArgoCD) prepareKeycloakConfig(cr *argoprojv1a1.ArgoCD) (*keycl } // prepares a keycloak config which is used in creating keycloak realm configuration for kubernetes. -func (r *ReconcileArgoCD) prepareKeycloakConfigForK8s(cr *argoprojv1a1.ArgoCD) (*keycloakConfig, error) { +func (r *ReconcileArgoCD) prepareKeycloakConfigForK8s(cr *argoproj.ArgoCD) (*keycloakConfig, error) { // Get keycloak hostname from ingress. // keycloak hostname is required to post realm configuration to keycloak when keycloak cannot be accessed using service name @@ -1017,7 +1017,7 @@ func createRealmConfig(cfg *keycloakConfig) ([]byte, error) { } // Gets Keycloak Server cert. This cert is used to authenticate the api calls to the Keycloak service. -func (r *ReconcileArgoCD) getKCServerCert(cr *argoprojv1a1.ArgoCD) ([]byte, error) { +func (r *ReconcileArgoCD) getKCServerCert(cr *argoproj.ArgoCD) ([]byte, error) { sslCertsSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -1043,7 +1043,7 @@ func getOAuthClient(ns string) string { } // Updates OIDC configuration for ArgoCD. -func (r *ReconcileArgoCD) updateArgoCDConfiguration(cr *argoprojv1a1.ArgoCD, kRouteURL string) error { +func (r *ReconcileArgoCD) updateArgoCDConfiguration(cr *argoproj.ArgoCD, kRouteURL string) error { // Update the ArgoCD client secret for OIDC in argocd-secret. argoCDSecret := &corev1.Secret{ @@ -1189,7 +1189,7 @@ func handleKeycloakPodDeletion(dc *oappsv1.DeploymentConfig) error { return nil } -func (r *ReconcileArgoCD) reconcileKeycloakConfiguration(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileKeycloakConfiguration(cr *argoproj.ArgoCD) error { // TemplateAPI is available, Install keycloak using openshift templates. if IsTemplateAPIAvailable() { @@ -1207,7 +1207,7 @@ func (r *ReconcileArgoCD) reconcileKeycloakConfiguration(cr *argoprojv1a1.ArgoCD return nil } -func deleteKeycloakConfiguration(cr *argoprojv1a1.ArgoCD) error { +func deleteKeycloakConfiguration(cr *argoproj.ArgoCD) error { // If SSO is installed using OpenShift templates. if IsTemplateAPIAvailable() { @@ -1226,7 +1226,7 @@ func deleteKeycloakConfiguration(cr *argoprojv1a1.ArgoCD) error { } // Delete Keycloak configuration for OpenShift -func deleteKeycloakConfigForOpenShift(cr *argoprojv1a1.ArgoCD) error { +func deleteKeycloakConfigForOpenShift(cr *argoproj.ArgoCD) error { cfg, err := config.GetConfig() if err != nil { log.Error(err, fmt.Sprintf("unable to get k8s config for ArgoCD %s in namespace %s", @@ -1264,7 +1264,7 @@ func deleteKeycloakConfigForOpenShift(cr *argoprojv1a1.ArgoCD) error { } // Delete OpenShift OAuthClient -func deleteOAuthClient(cr *argoprojv1a1.ArgoCD) error { +func deleteOAuthClient(cr *argoproj.ArgoCD) error { cfg, err := config.GetConfig() if err != nil { @@ -1307,7 +1307,7 @@ func deleteOAuthClient(cr *argoprojv1a1.ArgoCD) error { } // Delete Keycloak configuration for Kubernetes -func deleteKeycloakConfigForK8s(cr *argoprojv1a1.ArgoCD) error { +func deleteKeycloakConfigForK8s(cr *argoproj.ArgoCD) error { cfg, err := config.GetConfig() if err != nil { @@ -1354,7 +1354,7 @@ func deleteKeycloakConfigForK8s(cr *argoprojv1a1.ArgoCD) error { } // Installs and configures Keycloak for OpenShift -func (r *ReconcileArgoCD) reconcileKeycloakForOpenShift(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileKeycloakForOpenShift(cr *argoproj.ArgoCD) error { templateInstanceRef, err := newKeycloakTemplateInstance(cr) if err != nil { @@ -1473,7 +1473,7 @@ func (r *ReconcileArgoCD) reconcileKeycloakForOpenShift(cr *argoprojv1a1.ArgoCD) } // Installs and configures Keycloak for Kubernetes -func (r *ReconcileArgoCD) reconcileKeycloak(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileKeycloak(cr *argoproj.ArgoCD) error { err := r.newKeycloakInstance(cr) if err != nil { diff --git a/controllers/argocd/keycloak_test.go b/controllers/argocd/keycloak_test.go index 6952ecf58..d89ccb152 100644 --- a/controllers/argocd/keycloak_test.go +++ b/controllers/argocd/keycloak_test.go @@ -26,9 +26,7 @@ import ( resourcev1 "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoappv1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -86,8 +84,8 @@ func TestKeycloakContainerImage(t *testing.T) { name string setEnvVarFunc func(*testing.T, string) envVar string - argoCD *argoprojv1alpha1.ArgoCD - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + argoCD *argoproj.ArgoCD + updateCrFunc func(cr *argoproj.ArgoCD) templateAPIFound bool wantContainerImage string }{ @@ -95,9 +93,9 @@ func TestKeycloakContainerImage(t *testing.T) { name: "no .spec.sso, no ArgoCDKeycloakImageEnvName env var set", setEnvVarFunc: nil, envVar: "", - argoCD: makeArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), updateCrFunc: nil, @@ -108,9 +106,9 @@ func TestKeycloakContainerImage(t *testing.T) { name: "no .spec.sso, no ArgoCDKeycloakImageEnvName env var set - for OCP", setEnvVarFunc: nil, envVar: "", - argoCD: makeArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), updateCrFunc: nil, @@ -123,9 +121,9 @@ func TestKeycloakContainerImage(t *testing.T) { t.Setenv(common.ArgoCDKeycloakImageEnvName, s) }, envVar: "envImage:latest", - argoCD: makeArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), updateCrFunc: nil, @@ -138,15 +136,15 @@ func TestKeycloakContainerImage(t *testing.T) { t.Setenv(common.ArgoCDKeycloakImageEnvName, s) }, envVar: "envImage:latest", - argoCD: makeArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, - Keycloak: &v1alpha1.ArgoCDKeycloakSpec{ + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, + Keycloak: &argoproj.ArgoCDKeycloakSpec{ Image: "crImage", Version: "crVersion", }, @@ -181,7 +179,7 @@ func TestNewKeycloakTemplateInstance(t *testing.T) { defer removeTemplateAPI() a := makeTestArgoCD() - a.Spec.SSO = &argoappv1.ArgoCDSSOSpec{ + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "keycloak", } tmplInstance, err := newKeycloakTemplateInstance(a) @@ -197,7 +195,7 @@ func TestNewKeycloakTemplate(t *testing.T) { defer removeTemplateAPI() a := makeTestArgoCD() - a.Spec.SSO = &argoappv1.ArgoCDSSOSpec{ + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "keycloak", } tmpl, err := newKeycloakTemplate(a) @@ -213,7 +211,7 @@ func TestNewKeycloakTemplate_testDeploymentConfig(t *testing.T) { defer removeTemplateAPI() a := makeTestArgoCD() - a.Spec.SSO = &argoappv1.ArgoCDSSOSpec{ + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "keycloak", } dc := getKeycloakDeploymentConfigTemplate(a) @@ -246,7 +244,7 @@ func TestNewKeycloakTemplate_testKeycloakContainer(t *testing.T) { defer removeTemplateAPI() a := makeTestArgoCD() - a.Spec.SSO = &argoappv1.ArgoCDSSOSpec{ + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "keycloak", } kc := getKeycloakContainer(a) @@ -262,15 +260,15 @@ func TestKeycloakResources(t *testing.T) { tests := []struct { name string - argoCD *argoprojv1alpha1.ArgoCD - updateCrFunc func(cr *argoprojv1alpha1.ArgoCD) + argoCD *argoproj.ArgoCD + updateCrFunc func(cr *argoproj.ArgoCD) wantResources corev1.ResourceRequirements }{ { name: "default", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), updateCrFunc: nil, @@ -278,14 +276,14 @@ func TestKeycloakResources(t *testing.T) { }, { name: "override with .spec.sso.keycloak", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), - updateCrFunc: func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Keycloak: &v1alpha1.ArgoCDKeycloakSpec{ + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Keycloak: &argoproj.ArgoCDKeycloakSpec{ Resources: &fR, }, } @@ -374,24 +372,24 @@ func TestKeycloak_testServerCert(t *testing.T) { func TestKeycloakConfigVerifyTLSForOpenShift(t *testing.T) { tests := []struct { name string - argoCD *v1alpha1.ArgoCD + argoCD *argoproj.ArgoCD desiredVerifyTLS bool }{ { name: ".spec.sso.keycloak.verifyTLS nil", - argoCD: makeTestArgoCD(func(ac *argoprojv1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, } }), desiredVerifyTLS: true, }, { name: ".spec.sso.keycloak.verifyTLS false", - argoCD: makeTestArgoCD(func(ac *argoprojv1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, - Keycloak: &v1alpha1.ArgoCDKeycloakSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, + Keycloak: &argoproj.ArgoCDKeycloakSpec{ VerifyTLS: boolPtr(false), }, } @@ -400,10 +398,10 @@ func TestKeycloakConfigVerifyTLSForOpenShift(t *testing.T) { }, { name: ".spec.sso.keycloak.verifyTLS true", - argoCD: makeTestArgoCD(func(ac *argoprojv1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoappv1.SSOProviderTypeKeycloak, - Keycloak: &v1alpha1.ArgoCDKeycloakSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, + Keycloak: &argoproj.ArgoCDKeycloakSpec{ VerifyTLS: boolPtr(true), }, } @@ -469,7 +467,7 @@ func TestKeycloakConfigVerifyTLSForOpenShift(t *testing.T) { func TestKeycloak_NodeLabelSelector(t *testing.T) { a := makeTestArgoCDForKeycloak() - a.Spec.NodePlacement = &argoappv1.ArgoCDNodePlacementSpec{ + a.Spec.NodePlacement = &argoproj.ArgoCDNodePlacementSpec{ NodeSelector: deploymentDefaultNodeSelector(), Tolerations: deploymentDefaultTolerations(), } diff --git a/controllers/argocd/notifications.go b/controllers/argocd/notifications.go index 79a4766ed..5e0699568 100644 --- a/controllers/argocd/notifications.go +++ b/controllers/argocd/notifications.go @@ -14,12 +14,12 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) -func (r *ReconcileArgoCD) reconcileNotificationsController(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileNotificationsController(cr *argoproj.ArgoCD) error { log.Info("reconciling notifications serviceaccount") sa, err := r.reconcileNotificationsServiceAccount(cr) @@ -61,7 +61,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsController(cr *argoprojv1a1.Argo // RoleBinding and deployment are dependent on these resouces. During deletion the order is reversed. // Deployment and RoleBinding must be deleted before the role and sa. deleteNotificationsResources will only be called during // delete events, so we don't need to worry about duplicate, recurring reconciliation calls -func (r *ReconcileArgoCD) deleteNotificationsResources(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) deleteNotificationsResources(cr *argoproj.ArgoCD) error { sa := &corev1.ServiceAccount{} role := &rbacv1.Role{} @@ -112,7 +112,7 @@ func (r *ReconcileArgoCD) deleteNotificationsResources(cr *argoprojv1a1.ArgoCD) return nil } -func (r *ReconcileArgoCD) reconcileNotificationsServiceAccount(cr *argoprojv1a1.ArgoCD) (*corev1.ServiceAccount, error) { +func (r *ReconcileArgoCD) reconcileNotificationsServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { sa := newServiceAccountWithName(common.ArgoCDNotificationsControllerComponent, cr) @@ -147,7 +147,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsServiceAccount(cr *argoprojv1a1. return sa, nil } -func (r *ReconcileArgoCD) reconcileNotificationsRole(cr *argoprojv1a1.ArgoCD) (*rbacv1.Role, error) { +func (r *ReconcileArgoCD) reconcileNotificationsRole(cr *argoproj.ArgoCD) (*rbacv1.Role, error) { policyRules := policyRuleForNotificationsController() desiredRole := newRole(common.ArgoCDNotificationsControllerComponent, policyRules, cr) @@ -194,7 +194,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsRole(cr *argoprojv1a1.ArgoCD) (* return desiredRole, nil } -func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoprojv1a1.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { +func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoproj.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { desiredRoleBinding := newRoleBindingWithname(common.ArgoCDNotificationsControllerComponent, cr) desiredRoleBinding.RoleRef = rbacv1.RoleRef{ @@ -255,7 +255,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoprojv1a1.Arg return nil } -func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoprojv1a1.ArgoCD, sa *corev1.ServiceAccount) error { +func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { desiredDeployment := newDeploymentWithSuffix("notifications-controller", "controller", cr) @@ -434,7 +434,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoprojv1a1.Argo // reconcileNotificationsConfigMap only creates/deletes the argocd-notifications-cm based on whether notifications is enabled/disabled in the CR // It does not reconcile/overwrite any fields or information in the configmap itself -func (r *ReconcileArgoCD) reconcileNotificationsConfigMap(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileNotificationsConfigMap(cr *argoproj.ArgoCD) error { desiredConfigMap := newConfigMapWithName("argocd-notifications-cm", cr) desiredConfigMap.Data = getDefaultNotificationsConfig() @@ -480,7 +480,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsConfigMap(cr *argoprojv1a1.ArgoC // reconcileNotificationsSecret only creates/deletes the argocd-notifications-secret based on whether notifications is enabled/disabled in the CR // It does not reconcile/overwrite any fields or information in the secret itself -func (r *ReconcileArgoCD) reconcileNotificationsSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileNotificationsSecret(cr *argoproj.ArgoCD) error { desiredSecret := argoutil.NewSecretWithName(cr, "argocd-notifications-secret") @@ -523,7 +523,7 @@ func (r *ReconcileArgoCD) reconcileNotificationsSecret(cr *argoprojv1a1.ArgoCD) return nil } -func getNotificationsCommand(cr *argoprojv1a1.ArgoCD) []string { +func getNotificationsCommand(cr *argoproj.ArgoCD) []string { cmd := make([]string, 0) cmd = append(cmd, "argocd-notifications") @@ -535,7 +535,7 @@ func getNotificationsCommand(cr *argoprojv1a1.ArgoCD) []string { } // getNotificationsResources will return the ResourceRequirements for the Notifications container. -func getNotificationsResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getNotificationsResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR diff --git a/controllers/argocd/notifications_test.go b/controllers/argocd/notifications_test.go index 2648f5a0c..3b4951e02 100644 --- a/controllers/argocd/notifications_test.go +++ b/controllers/argocd/notifications_test.go @@ -15,14 +15,14 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" logf "sigs.k8s.io/controller-runtime/pkg/log" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) func TestReconcileNotifications_CreateRoles(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) @@ -54,7 +54,7 @@ func TestReconcileNotifications_CreateRoles(t *testing.T) { func TestReconcileNotifications_CreateServiceAccount(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) @@ -85,7 +85,7 @@ func TestReconcileNotifications_CreateServiceAccount(t *testing.T) { func TestReconcileNotifications_CreateRoleBinding(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) r := makeTestReconciler(t, a) @@ -121,7 +121,7 @@ func TestReconcileNotifications_CreateRoleBinding(t *testing.T) { func TestReconcileNotifications_CreateDeployments(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) @@ -232,7 +232,7 @@ func TestReconcileNotifications_CreateDeployments(t *testing.T) { func TestReconcileNotifications_CreateSecret(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) @@ -257,7 +257,7 @@ func TestReconcileNotifications_CreateSecret(t *testing.T) { func TestReconcileNotifications_CreateConfigMap(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) @@ -290,7 +290,7 @@ func TestReconcileNotifications_testEnvVars(t *testing.T) { Value: "bar", }, } - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true a.Spec.Notifications.Env = envMap }) @@ -348,7 +348,7 @@ func TestReconcileNotifications_testEnvVars(t *testing.T) { func TestReconcileNotifications_testLogLevel(t *testing.T) { testLogLevel := "debug" - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true a.Spec.Notifications.LogLevel = testLogLevel }) diff --git a/controllers/argocd/notifications_util.go b/controllers/argocd/notifications_util.go index 710aa361b..4c99c668c 100644 --- a/controllers/argocd/notifications_util.go +++ b/controllers/argocd/notifications_util.go @@ -1,6 +1,6 @@ package argocd -import argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" +import argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" // getDefaultNotificationsConfig returns a map that contains default triggers and template configurations for argocd-notifications-cm func getDefaultNotificationsConfig() map[string]string { @@ -546,7 +546,7 @@ teams: // getArgoCDNotificationsControllerReplicas will return the size value for the argocd-notifications-controller replica count if it // has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or // replicas value is < 0. -func getArgoCDNotificationsControllerReplicas(cr *argoprojv1a1.ArgoCD) *int32 { +func getArgoCDNotificationsControllerReplicas(cr *argoproj.ArgoCD) *int32 { if cr.Spec.Notifications.Replicas != nil && *cr.Spec.Notifications.Replicas >= 0 { return cr.Spec.Notifications.Replicas } diff --git a/controllers/argocd/prometheus.go b/controllers/argocd/prometheus.go index 236757858..a1b24a1df 100644 --- a/controllers/argocd/prometheus.go +++ b/controllers/argocd/prometheus.go @@ -23,7 +23,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -31,7 +31,7 @@ import ( var prometheusAPIFound = false // getPrometheusHost will return the hostname value for Prometheus. -func getPrometheusHost(cr *argoprojv1a1.ArgoCD) string { +func getPrometheusHost(cr *argoproj.ArgoCD) string { host := nameWithSuffix("prometheus", cr) if len(cr.Spec.Prometheus.Host) > 0 { host = cr.Spec.Prometheus.Host @@ -40,7 +40,7 @@ func getPrometheusHost(cr *argoprojv1a1.ArgoCD) string { } // getPrometheusSize will return the size value for the Prometheus replica count. -func getPrometheusReplicas(cr *argoprojv1a1.ArgoCD) *int32 { +func getPrometheusReplicas(cr *argoproj.ArgoCD) *int32 { replicas := common.ArgoCDDefaultPrometheusReplicas if cr.Spec.Prometheus.Size != nil { if *cr.Spec.Prometheus.Size >= 0 && *cr.Spec.Prometheus.Size != replicas { @@ -56,7 +56,7 @@ func IsPrometheusAPIAvailable() bool { } // hasPrometheusSpecChanged will return true if the supported properties differs in the actual versus the desired state. -func hasPrometheusSpecChanged(actual *monitoringv1.Prometheus, desired *argoprojv1a1.ArgoCD) bool { +func hasPrometheusSpecChanged(actual *monitoringv1.Prometheus, desired *argoproj.ArgoCD) bool { // Replica count if desired.Spec.Prometheus.Size != nil && *desired.Spec.Prometheus.Size >= 0 { // Valid replica count specified in desired state if actual.Spec.Replicas != nil { // Actual replicas value is set @@ -85,7 +85,7 @@ func verifyPrometheusAPI() error { } // newPrometheus returns a new Prometheus instance for the given ArgoCD. -func newPrometheus(cr *argoprojv1a1.ArgoCD) *monitoringv1.Prometheus { +func newPrometheus(cr *argoproj.ArgoCD) *monitoringv1.Prometheus { return &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -96,7 +96,7 @@ func newPrometheus(cr *argoprojv1a1.ArgoCD) *monitoringv1.Prometheus { } // newServiceMonitor returns a new ServiceMonitor instance. -func newServiceMonitor(cr *argoprojv1a1.ArgoCD) *monitoringv1.ServiceMonitor { +func newServiceMonitor(cr *argoproj.ArgoCD) *monitoringv1.ServiceMonitor { return &monitoringv1.ServiceMonitor{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -107,7 +107,7 @@ func newServiceMonitor(cr *argoprojv1a1.ArgoCD) *monitoringv1.ServiceMonitor { } // newServiceMonitorWithName returns a new ServiceMonitor instance for the given ArgoCD using the given name. -func newServiceMonitorWithName(name string, cr *argoprojv1a1.ArgoCD) *monitoringv1.ServiceMonitor { +func newServiceMonitorWithName(name string, cr *argoproj.ArgoCD) *monitoringv1.ServiceMonitor { svcmon := newServiceMonitor(cr) svcmon.ObjectMeta.Name = name @@ -120,12 +120,12 @@ func newServiceMonitorWithName(name string, cr *argoprojv1a1.ArgoCD) *monitoring } // newServiceMonitorWithSuffix returns a new ServiceMonitor instance for the given ArgoCD using the given suffix. -func newServiceMonitorWithSuffix(suffix string, cr *argoprojv1a1.ArgoCD) *monitoringv1.ServiceMonitor { +func newServiceMonitorWithSuffix(suffix string, cr *argoproj.ArgoCD) *monitoringv1.ServiceMonitor { return newServiceMonitorWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), cr) } // reconcileMetricsServiceMonitor will ensure that the ServiceMonitor is present for the ArgoCD metrics Service. -func (r *ReconcileArgoCD) reconcileMetricsServiceMonitor(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileMetricsServiceMonitor(cr *argoproj.ArgoCD) error { sm := newServiceMonitorWithSuffix(common.ArgoCDKeyMetrics, cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { if !cr.Spec.Prometheus.Enabled { @@ -157,7 +157,7 @@ func (r *ReconcileArgoCD) reconcileMetricsServiceMonitor(cr *argoprojv1a1.ArgoCD } // reconcilePrometheus will ensure that Prometheus is present for ArgoCD metrics. -func (r *ReconcileArgoCD) reconcilePrometheus(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcilePrometheus(cr *argoproj.ArgoCD) error { prometheus := newPrometheus(cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, prometheus.Name, prometheus) { if !cr.Spec.Prometheus.Enabled { @@ -186,7 +186,7 @@ func (r *ReconcileArgoCD) reconcilePrometheus(cr *argoprojv1a1.ArgoCD) error { } // reconcileRepoServerServiceMonitor will ensure that the ServiceMonitor is present for the Repo Server metrics Service. -func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoproj.ArgoCD) error { sm := newServiceMonitorWithSuffix("repo-server-metrics", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { if !cr.Spec.Prometheus.Enabled { @@ -218,7 +218,7 @@ func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoprojv1a1.Arg } // reconcileServerMetricsServiceMonitor will ensure that the ServiceMonitor is present for the ArgoCD Server metrics Service. -func (r *ReconcileArgoCD) reconcileServerMetricsServiceMonitor(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServerMetricsServiceMonitor(cr *argoproj.ArgoCD) error { sm := newServiceMonitorWithSuffix("server-metrics", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { if !cr.Spec.Prometheus.Enabled { @@ -250,7 +250,7 @@ func (r *ReconcileArgoCD) reconcileServerMetricsServiceMonitor(cr *argoprojv1a1. } // reconcilePrometheusRule reconciles the PrometheusRule that triggers alerts based on workload statuses -func (r *ReconcileArgoCD) reconcilePrometheusRule(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcilePrometheusRule(cr *argoproj.ArgoCD) error { promRule := newPrometheusRule(cr.Namespace, "argocd-component-status-alert") diff --git a/controllers/argocd/prometheus_test.go b/controllers/argocd/prometheus_test.go index 31a47cc2b..0cebeb7b8 100644 --- a/controllers/argocd/prometheus_test.go +++ b/controllers/argocd/prometheus_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/types" @@ -15,13 +15,13 @@ import ( func TestReconcileWorkloadStatusAlertRule(t *testing.T) { tests := []struct { name string - argocd *argoprojv1alpha1.ArgoCD + argocd *argoproj.ArgoCD wantPromRuleFound bool existingPromRule bool }{ { name: "monitoring enabled, no existing prom rule", - argocd: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argocd: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.Monitoring.Enabled = true }), existingPromRule: false, @@ -29,7 +29,7 @@ func TestReconcileWorkloadStatusAlertRule(t *testing.T) { }, { name: "monitoring disabled, no existing prom rule", - argocd: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argocd: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.Monitoring.Enabled = false }), existingPromRule: false, @@ -37,7 +37,7 @@ func TestReconcileWorkloadStatusAlertRule(t *testing.T) { }, { name: "monitoring enabled, existing prom rule", - argocd: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argocd: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.Monitoring.Enabled = true }), existingPromRule: true, @@ -45,7 +45,7 @@ func TestReconcileWorkloadStatusAlertRule(t *testing.T) { }, { name: "monitoring disabled, existing prom rule", - argocd: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argocd: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.Monitoring.Enabled = false }), existingPromRule: true, diff --git a/controllers/argocd/role.go b/controllers/argocd/role.go index f7c162c1d..923cfe159 100644 --- a/controllers/argocd/role.go +++ b/controllers/argocd/role.go @@ -14,13 +14,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // newRole returns a new Role instance. -func newRole(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.Role { +func newRole(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) *v1.Role { return &v1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: generateResourceName(name, cr), @@ -31,7 +31,7 @@ func newRole(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.Ro } } -func newRoleForApplicationSourceNamespaces(namespace string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.Role { +func newRoleForApplicationSourceNamespaces(namespace string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) *v1.Role { return &v1.Role{ ObjectMeta: metav1.ObjectMeta{ Name: getRoleNameForApplicationSourceNamespaces(namespace, cr), @@ -42,16 +42,16 @@ func newRoleForApplicationSourceNamespaces(namespace string, rules []v1.PolicyRu } } -func generateResourceName(argoComponentName string, cr *argoprojv1a1.ArgoCD) string { +func generateResourceName(argoComponentName string, cr *argoproj.ArgoCD) string { return cr.Name + "-" + argoComponentName } // GenerateUniqueResourceName generates unique names for cluster scoped resources -func GenerateUniqueResourceName(argoComponentName string, cr *argoprojv1a1.ArgoCD) string { +func GenerateUniqueResourceName(argoComponentName string, cr *argoproj.ArgoCD) string { return cr.Name + "-" + cr.Namespace + "-" + argoComponentName } -func newClusterRole(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) *v1.ClusterRole { +func newClusterRole(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) *v1.ClusterRole { return &v1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: GenerateUniqueResourceName(name, cr), @@ -63,7 +63,7 @@ func newClusterRole(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) } // reconcileRoles will ensure that all ArgoCD Service Accounts are configured. -func (r *ReconcileArgoCD) reconcileRoles(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRoles(cr *argoproj.ArgoCD) error { params := getPolicyRuleList(r.Client) for _, param := range params { @@ -98,7 +98,7 @@ func (r *ReconcileArgoCD) reconcileRoles(cr *argoprojv1a1.ArgoCD) error { // reconcileRole, reconciles the policy rules for different ArgoCD components, for each namespace // Managed by a single instance of ArgoCD. -func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) ([]*v1.Role, error) { +func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule, cr *argoproj.ArgoCD) ([]*v1.Role, error) { var roles []*v1.Role // create policy rules for each namespace @@ -113,7 +113,7 @@ func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule continue } - list := &argoprojv1a1.ArgoCDList{} + list := &argoproj.ArgoCDList{} listOption := &client.ListOptions{Namespace: namespace.Name} err := r.Client.List(context.TODO(), list, listOption) if err != nil { @@ -186,7 +186,7 @@ func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule return roles, nil } -func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name string, policyRules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name string, policyRules []v1.PolicyRule, cr *argoproj.ArgoCD) error { var roles []*v1.Role // create policy rules for each source namespace for ArgoCD Server @@ -272,7 +272,7 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin return nil } -func (r *ReconcileArgoCD) reconcileClusterRole(name string, policyRules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) (*v1.ClusterRole, error) { +func (r *ReconcileArgoCD) reconcileClusterRole(name string, policyRules []v1.PolicyRule, cr *argoproj.ArgoCD) (*v1.ClusterRole, error) { allowed := false if allowedNamespace(cr.Namespace, os.Getenv("ARGOCD_CLUSTER_CONFIG_NAMESPACES")) { allowed = true diff --git a/controllers/argocd/role_test.go b/controllers/argocd/role_test.go index 61c1e13f8..db5bc53d9 100644 --- a/controllers/argocd/role_test.go +++ b/controllers/argocd/role_test.go @@ -14,7 +14,7 @@ import ( "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) @@ -140,7 +140,7 @@ func TestReconcileArgoCD_reconcileRoleForApplicationSourceNamespaces(t *testing. logf.SetLogger(ZapLogger(true)) sourceNamespace := "newNamespaceTest" a := makeTestArgoCD() - a.Spec = v1alpha1.ArgoCDSpec{ + a.Spec = argoproj.ArgoCDSpec{ SourceNamespaces: []string{ sourceNamespace, }, diff --git a/controllers/argocd/rolebinding.go b/controllers/argocd/rolebinding.go index 4be09c3c0..37a45b22f 100644 --- a/controllers/argocd/rolebinding.go +++ b/controllers/argocd/rolebinding.go @@ -14,13 +14,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // newClusterRoleBinding returns a new ClusterRoleBinding instance. -func newClusterRoleBinding(cr *argoprojv1a1.ArgoCD) *v1.ClusterRoleBinding { +func newClusterRoleBinding(cr *argoproj.ArgoCD) *v1.ClusterRoleBinding { return &v1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -31,7 +31,7 @@ func newClusterRoleBinding(cr *argoprojv1a1.ArgoCD) *v1.ClusterRoleBinding { } // newClusterRoleBindingWithname creates a new ClusterRoleBinding with the given name for the given ArgCD. -func newClusterRoleBindingWithname(name string, cr *argoprojv1a1.ArgoCD) *v1.ClusterRoleBinding { +func newClusterRoleBindingWithname(name string, cr *argoproj.ArgoCD) *v1.ClusterRoleBinding { roleBinding := newClusterRoleBinding(cr) roleBinding.Name = GenerateUniqueResourceName(name, cr) @@ -43,7 +43,7 @@ func newClusterRoleBindingWithname(name string, cr *argoprojv1a1.ArgoCD) *v1.Clu } // newRoleBinding returns a new RoleBinding instance. -func newRoleBinding(cr *argoprojv1a1.ArgoCD) *v1.RoleBinding { +func newRoleBinding(cr *argoproj.ArgoCD) *v1.RoleBinding { return &v1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -55,7 +55,7 @@ func newRoleBinding(cr *argoprojv1a1.ArgoCD) *v1.RoleBinding { } // newRoleBindingForSupportNamespaces returns a new RoleBinding instance. -func newRoleBindingForSupportNamespaces(cr *argoprojv1a1.ArgoCD, namespace string) *v1.RoleBinding { +func newRoleBindingForSupportNamespaces(cr *argoproj.ArgoCD, namespace string) *v1.RoleBinding { return &v1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: getRoleBindingNameForSourceNamespaces(cr.Name, cr.Namespace, namespace), @@ -71,7 +71,7 @@ func getRoleBindingNameForSourceNamespaces(argocdName, argocdNamespace, targetNa } // newRoleBindingWithname creates a new RoleBinding with the given name for the given ArgCD. -func newRoleBindingWithname(name string, cr *argoprojv1a1.ArgoCD) *v1.RoleBinding { +func newRoleBindingWithname(name string, cr *argoproj.ArgoCD) *v1.RoleBinding { roleBinding := newRoleBinding(cr) roleBinding.ObjectMeta.Name = fmt.Sprintf("%s-%s", cr.Name, name) @@ -83,7 +83,7 @@ func newRoleBindingWithname(name string, cr *argoprojv1a1.ArgoCD) *v1.RoleBindin } // reconcileRoleBindings will ensure that all ArgoCD RoleBindings are configured. -func (r *ReconcileArgoCD) reconcileRoleBindings(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRoleBindings(cr *argoproj.ArgoCD) error { params := getPolicyRuleList(r.Client) for _, param := range params { @@ -97,7 +97,7 @@ func (r *ReconcileArgoCD) reconcileRoleBindings(cr *argoprojv1a1.ArgoCD) error { // reconcileRoleBinding, creates RoleBindings for every role and associates it with the right ServiceAccount. // This would create RoleBindings for all the namespaces managed by the ArgoCD instance. -func (r *ReconcileArgoCD) reconcileRoleBinding(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRoleBinding(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) error { var sa *corev1.ServiceAccount var error error @@ -120,7 +120,7 @@ func (r *ReconcileArgoCD) reconcileRoleBinding(name string, rules []v1.PolicyRul continue } - list := &argoprojv1a1.ArgoCDList{} + list := &argoproj.ArgoCDList{} listOption := &client.ListOptions{Namespace: namespace.Name} err := r.Client.List(context.TODO(), list, listOption) if err != nil { @@ -234,7 +234,7 @@ func (r *ReconcileArgoCD) reconcileRoleBinding(name string, rules []v1.PolicyRul continue } - list := &argoprojv1a1.ArgoCDList{} + list := &argoproj.ArgoCDList{} listOption := &client.ListOptions{Namespace: namespace.Name} err := r.Client.List(context.TODO(), list, listOption) if err != nil { @@ -319,12 +319,12 @@ func getCustomRoleName(name string) string { } // Returns the name of the role for the source namespaces for ArgoCDServer in the format of "sourceNamespace_targetNamespace_argocd-server" -func getRoleNameForApplicationSourceNamespaces(targetNamespace string, cr *argoprojv1a1.ArgoCD) string { +func getRoleNameForApplicationSourceNamespaces(targetNamespace string, cr *argoproj.ArgoCD) string { return fmt.Sprintf("%s_%s", cr.Name, targetNamespace) } // newRoleBindingWithNameForApplicationSourceNamespaces creates a new RoleBinding with the given name for the source namespaces of ArgoCD Server. -func newRoleBindingWithNameForApplicationSourceNamespaces(namespace string, cr *argoprojv1a1.ArgoCD) *v1.RoleBinding { +func newRoleBindingWithNameForApplicationSourceNamespaces(namespace string, cr *argoproj.ArgoCD) *v1.RoleBinding { roleBinding := newRoleBindingForSupportNamespaces(cr, namespace) labels := roleBinding.ObjectMeta.Labels @@ -334,7 +334,7 @@ func newRoleBindingWithNameForApplicationSourceNamespaces(namespace string, cr * return roleBinding } -func (r *ReconcileArgoCD) reconcileClusterRoleBinding(name string, role *v1.ClusterRole, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileClusterRoleBinding(name string, role *v1.ClusterRole, cr *argoproj.ArgoCD) error { // get expected name roleBinding := newClusterRoleBindingWithname(name, cr) diff --git a/controllers/argocd/rolebinding_test.go b/controllers/argocd/rolebinding_test.go index e922d21b8..ac25e1274 100644 --- a/controllers/argocd/rolebinding_test.go +++ b/controllers/argocd/rolebinding_test.go @@ -12,7 +12,7 @@ import ( "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) @@ -215,7 +215,7 @@ func TestReconcileArgoCD_reconcileRoleBinding_forSourceNamespaces(t *testing.T) logf.SetLogger(ZapLogger(true)) sourceNamespace := "newNamespaceTest" a := makeTestArgoCD() - a.Spec = v1alpha1.ArgoCDSpec{ + a.Spec = argoproj.ArgoCDSpec{ SourceNamespaces: []string{ sourceNamespace, }, diff --git a/controllers/argocd/route.go b/controllers/argocd/route.go index 70daa62e2..bbf07d47c 100644 --- a/controllers/argocd/route.go +++ b/controllers/argocd/route.go @@ -23,7 +23,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -46,7 +46,7 @@ func verifyRouteAPI() error { } // newRoute returns a new Route instance for the given ArgoCD. -func newRoute(cr *argoprojv1a1.ArgoCD) *routev1.Route { +func newRoute(cr *argoproj.ArgoCD) *routev1.Route { return &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -57,7 +57,7 @@ func newRoute(cr *argoprojv1a1.ArgoCD) *routev1.Route { } // newRouteWithName returns a new Route with the given name and ArgoCD. -func newRouteWithName(name string, cr *argoprojv1a1.ArgoCD) *routev1.Route { +func newRouteWithName(name string, cr *argoproj.ArgoCD) *routev1.Route { route := newRoute(cr) route.ObjectMeta.Name = name @@ -69,12 +69,12 @@ func newRouteWithName(name string, cr *argoprojv1a1.ArgoCD) *routev1.Route { } // newRouteWithSuffix returns a new Route with the given name suffix for the ArgoCD. -func newRouteWithSuffix(suffix string, cr *argoprojv1a1.ArgoCD) *routev1.Route { +func newRouteWithSuffix(suffix string, cr *argoproj.ArgoCD) *routev1.Route { return newRouteWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), cr) } // reconcileRoutes will ensure that all ArgoCD Routes are present. -func (r *ReconcileArgoCD) reconcileRoutes(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRoutes(cr *argoproj.ArgoCD) error { if err := r.reconcileGrafanaRoute(cr); err != nil { return err } @@ -95,7 +95,7 @@ func (r *ReconcileArgoCD) reconcileRoutes(cr *argoprojv1a1.ArgoCD) error { } // reconcileGrafanaRoute will ensure that the ArgoCD Grafana Route is present. -func (r *ReconcileArgoCD) reconcileGrafanaRoute(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaRoute(cr *argoproj.ArgoCD) error { route := newRouteWithSuffix("grafana", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, route.Name, route) { if !cr.Spec.Grafana.Enabled || !cr.Spec.Grafana.Route.Enabled { @@ -157,7 +157,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaRoute(cr *argoprojv1a1.ArgoCD) error { } // reconcilePrometheusRoute will ensure that the ArgoCD Prometheus Route is present. -func (r *ReconcileArgoCD) reconcilePrometheusRoute(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcilePrometheusRoute(cr *argoproj.ArgoCD) error { route := newRouteWithSuffix("prometheus", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, route.Name, route) { if !cr.Spec.Prometheus.Enabled || !cr.Spec.Prometheus.Route.Enabled { @@ -214,7 +214,7 @@ func (r *ReconcileArgoCD) reconcilePrometheusRoute(cr *argoprojv1a1.ArgoCD) erro } // reconcileServerRoute will ensure that the ArgoCD Server Route is present. -func (r *ReconcileArgoCD) reconcileServerRoute(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServerRoute(cr *argoproj.ArgoCD) error { route := newRouteWithSuffix("server", cr) found := argoutil.IsObjectFound(r.Client, cr.Namespace, route.Name, route) @@ -291,7 +291,7 @@ func (r *ReconcileArgoCD) reconcileServerRoute(cr *argoprojv1a1.ArgoCD) error { } // reconcileApplicationSetControllerWebhookRoute will ensure that the ArgoCD Server Route is present. -func (r *ReconcileArgoCD) reconcileApplicationSetControllerWebhookRoute(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileApplicationSetControllerWebhookRoute(cr *argoproj.ArgoCD) error { name := fmt.Sprintf("%s-%s", common.ApplicationSetServiceNameSuffix, "webhook") route := newRouteWithSuffix(name, cr) found := argoutil.IsObjectFound(r.Client, cr.Namespace, route.Name, route) diff --git a/controllers/argocd/route_test.go b/controllers/argocd/route_test.go index 2272335ee..4e3bd3fca 100644 --- a/controllers/argocd/route_test.go +++ b/controllers/argocd/route_test.go @@ -20,14 +20,14 @@ import ( configv1 "github.com/openshift/api/config/v1" routev1 "github.com/openshift/api/route/v1" - argov1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) func TestReconcileRouteSetLabels(t *testing.T) { routeAPIFound = true ctx := context.Background() logf.SetLogger(ZapLogger(true)) - argoCD := makeArgoCD(func(a *argov1alpha1.ArgoCD) { + argoCD := makeArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Route.Enabled = true labels := make(map[string]string) labels["my-key"] = "my-value" @@ -62,7 +62,7 @@ func TestReconcileRouteSetsInsecure(t *testing.T) { routeAPIFound = true ctx := context.Background() logf.SetLogger(ZapLogger(true)) - argoCD := makeArgoCD(func(a *argov1alpha1.ArgoCD) { + argoCD := makeArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Route.Enabled = true }) objs := []runtime.Object{ @@ -133,7 +133,7 @@ func TestReconcileRouteUnsetsInsecure(t *testing.T) { routeAPIFound = true ctx := context.Background() logf.SetLogger(ZapLogger(true)) - argoCD := makeArgoCD(func(a *argov1alpha1.ArgoCD) { + argoCD := makeArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Route.Enabled = true a.Spec.Server.Insecure = true }) @@ -201,10 +201,10 @@ func TestReconcileRouteUnsetsInsecure(t *testing.T) { } } -func makeReconciler(t *testing.T, acd *argov1alpha1.ArgoCD, objs ...runtime.Object) *ReconcileArgoCD { +func makeReconciler(t *testing.T, acd *argoproj.ArgoCD, objs ...runtime.Object) *ReconcileArgoCD { t.Helper() s := scheme.Scheme - s.AddKnownTypes(argov1alpha1.GroupVersion, acd) + s.AddKnownTypes(argoproj.GroupVersion, acd) routev1.Install(s) configv1.Install(s) cl := fake.NewFakeClient(objs...) @@ -214,13 +214,13 @@ func makeReconciler(t *testing.T, acd *argov1alpha1.ArgoCD, objs ...runtime.Obje } } -func makeArgoCD(opts ...func(*argov1alpha1.ArgoCD)) *argov1alpha1.ArgoCD { - argoCD := &argov1alpha1.ArgoCD{ +func makeArgoCD(opts ...func(*argoproj.ArgoCD)) *argoproj.ArgoCD { + argoCD := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: testArgoCDName, Namespace: testNamespace, }, - Spec: argov1alpha1.ArgoCDSpec{}, + Spec: argoproj.ArgoCDSpec{}, } for _, o := range opts { o(argoCD) diff --git a/controllers/argocd/secret.go b/controllers/argocd/secret.go index c2fe82c6f..59640db28 100644 --- a/controllers/argocd/secret.go +++ b/controllers/argocd/secret.go @@ -29,8 +29,7 @@ import ( argopass "github.com/argoproj/argo-cd/v2/util/password" tlsutil "github.com/operator-framework/operator-sdk/pkg/tls" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" @@ -80,7 +79,7 @@ func nowNano() string { } // newCASecret creates a new CA secret with the given suffix for the given ArgoCD. -func newCASecret(cr *argoprojv1a1.ArgoCD) (*corev1.Secret, error) { +func newCASecret(cr *argoproj.ArgoCD) (*corev1.Secret, error) { secret := argoutil.NewTLSSecret(cr, "ca") key, err := argoutil.NewPrivateKey() @@ -104,7 +103,7 @@ func newCASecret(cr *argoprojv1a1.ArgoCD) (*corev1.Secret, error) { } // newCertificateSecret creates a new secret using the given name suffix for the given TLS certificate. -func newCertificateSecret(suffix string, caCert *x509.Certificate, caKey *rsa.PrivateKey, cr *argoprojv1a1.ArgoCD) (*corev1.Secret, error) { +func newCertificateSecret(suffix string, caCert *x509.Certificate, caKey *rsa.PrivateKey, cr *argoproj.ArgoCD) (*corev1.Secret, error) { secret := argoutil.NewTLSSecret(cr, suffix) key, err := argoutil.NewPrivateKey() @@ -146,7 +145,7 @@ func newCertificateSecret(suffix string, caCert *x509.Certificate, caKey *rsa.Pr } // reconcileArgoSecret will ensure that the Argo CD Secret is present. -func (r *ReconcileArgoCD) reconcileArgoSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileArgoSecret(cr *argoproj.ArgoCD) error { clusterSecret := argoutil.NewSecretWithSuffix(cr, "cluster") secret := argoutil.NewSecretWithName(cr, common.ArgoCDSecretName) @@ -184,7 +183,7 @@ func (r *ReconcileArgoCD) reconcileArgoSecret(cr *argoprojv1a1.ArgoCD) error { common.ArgoCDKeyTLSPrivateKey: tlsSecret.Data[common.ArgoCDKeyTLSPrivateKey], } - if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == v1alpha1.SSOProviderTypeDex { + if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeDex { dexOIDCClientSecret, err := r.getDexOAuthClientSecret(cr) if err != nil { return nil @@ -199,7 +198,7 @@ func (r *ReconcileArgoCD) reconcileArgoSecret(cr *argoprojv1a1.ArgoCD) error { } // reconcileClusterMainSecret will ensure that the main Secret is present for the Argo CD cluster. -func (r *ReconcileArgoCD) reconcileClusterMainSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileClusterMainSecret(cr *argoproj.ArgoCD) error { secret := argoutil.NewSecretWithSuffix(cr, "cluster") if argoutil.IsObjectFound(r.Client, cr.Namespace, secret.Name, secret) { return nil // Secret found, do nothing @@ -221,7 +220,7 @@ func (r *ReconcileArgoCD) reconcileClusterMainSecret(cr *argoprojv1a1.ArgoCD) er } // reconcileClusterTLSSecret ensures the TLS Secret is created for the ArgoCD cluster. -func (r *ReconcileArgoCD) reconcileClusterTLSSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileClusterTLSSecret(cr *argoproj.ArgoCD) error { secret := argoutil.NewTLSSecret(cr, "tls") if argoutil.IsObjectFound(r.Client, cr.Namespace, secret.Name, secret) { return nil // Secret found, do nothing @@ -256,7 +255,7 @@ func (r *ReconcileArgoCD) reconcileClusterTLSSecret(cr *argoprojv1a1.ArgoCD) err } // reconcileClusterCASecret ensures the CA Secret is created for the ArgoCD cluster. -func (r *ReconcileArgoCD) reconcileClusterCASecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileClusterCASecret(cr *argoproj.ArgoCD) error { secret := argoutil.NewSecretWithSuffix(cr, "ca") if argoutil.IsObjectFound(r.Client, cr.Namespace, secret.Name, secret) { return nil // Secret found, do nothing @@ -274,7 +273,7 @@ func (r *ReconcileArgoCD) reconcileClusterCASecret(cr *argoprojv1a1.ArgoCD) erro } // reconcileClusterSecrets will reconcile all Secret resources for the ArgoCD cluster. -func (r *ReconcileArgoCD) reconcileClusterSecrets(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileClusterSecrets(cr *argoproj.ArgoCD) error { if err := r.reconcileClusterMainSecret(cr); err != nil { return err } @@ -299,7 +298,7 @@ func (r *ReconcileArgoCD) reconcileClusterSecrets(cr *argoprojv1a1.ArgoCD) error } // reconcileExistingArgoSecret will ensure that the Argo CD Secret is up to date. -func (r *ReconcileArgoCD) reconcileExistingArgoSecret(cr *argoprojv1a1.ArgoCD, secret *corev1.Secret, clusterSecret *corev1.Secret, tlsSecret *corev1.Secret) error { +func (r *ReconcileArgoCD) reconcileExistingArgoSecret(cr *argoproj.ArgoCD, secret *corev1.Secret, clusterSecret *corev1.Secret, tlsSecret *corev1.Secret) error { changed := false if secret.Data == nil { @@ -334,7 +333,7 @@ func (r *ReconcileArgoCD) reconcileExistingArgoSecret(cr *argoprojv1a1.ArgoCD, s changed = true } - if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == v1alpha1.SSOProviderTypeDex { + if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeDex { dexOIDCClientSecret, err := r.getDexOAuthClientSecret(cr) if err != nil { return err @@ -360,7 +359,7 @@ func (r *ReconcileArgoCD) reconcileExistingArgoSecret(cr *argoprojv1a1.ArgoCD, s } // reconcileGrafanaSecret will ensure that the Grafana Secret is present. -func (r *ReconcileArgoCD) reconcileGrafanaSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaSecret(cr *argoproj.ArgoCD) error { if !cr.Spec.Grafana.Enabled { return nil // Grafana not enabled, do nothing. } @@ -422,7 +421,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaSecret(cr *argoprojv1a1.ArgoCD) error } // reconcileClusterPermissionsSecret ensures ArgoCD instance is namespace-scoped -func (r *ReconcileArgoCD) reconcileClusterPermissionsSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileClusterPermissionsSecret(cr *argoproj.ArgoCD) error { var clusterConfigInstance bool secret := argoutil.NewSecretWithSuffix(cr, "default-cluster-config") secret.Labels[common.ArgoCDSecretTypeLabel] = "cluster" @@ -503,7 +502,7 @@ func (r *ReconcileArgoCD) reconcileClusterPermissionsSecret(cr *argoprojv1a1.Arg // has changed since our last reconciliation loop. It does so by comparing the // checksum of tls.crt and tls.key in the status of the ArgoCD CR against the // values calculated from the live state in the cluster. -func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoproj.ArgoCD) error { var tlsSecretObj corev1.Secret var sha256sum string @@ -571,7 +570,7 @@ func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoprojv1a1.ArgoCD) // has changed since our last reconciliation loop. It does so by comparing the // checksum of tls.crt and tls.key in the status of the ArgoCD CR against the // values calculated from the live state in the cluster. -func (r *ReconcileArgoCD) reconcileRedisTLSSecret(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileRedisTLSSecret(cr *argoproj.ArgoCD, useTLSForRedis bool) error { var tlsSecretObj corev1.Secret var sha256sum string @@ -670,7 +669,7 @@ func (r *ReconcileArgoCD) reconcileRedisTLSSecret(cr *argoprojv1a1.ArgoCD, useTL } // reconcileSecrets will reconcile all ArgoCD Secret resources. -func (r *ReconcileArgoCD) reconcileSecrets(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileSecrets(cr *argoproj.ArgoCD) error { if err := r.reconcileClusterSecrets(cr); err != nil { return err } @@ -682,7 +681,7 @@ func (r *ReconcileArgoCD) reconcileSecrets(cr *argoprojv1a1.ArgoCD) error { return nil } -func (r *ReconcileArgoCD) getClusterSecrets(cr *argoprojv1a1.ArgoCD) (*corev1.SecretList, error) { +func (r *ReconcileArgoCD) getClusterSecrets(cr *argoproj.ArgoCD) (*corev1.SecretList, error) { clusterSecrets := &corev1.SecretList{} opts := &client.ListOptions{ diff --git a/controllers/argocd/secret_test.go b/controllers/argocd/secret_test.go index f9527ac66..b3d7b470f 100644 --- a/controllers/argocd/secret_test.go +++ b/controllers/argocd/secret_test.go @@ -17,14 +17,13 @@ import ( "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) func Test_newCASecret(t *testing.T) { - cr := &argoprojv1alpha1.ArgoCD{ + cr := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: "test-argocd", Namespace: "argocd", @@ -55,7 +54,7 @@ func byteMapKeys(m map[string][]byte) []string { } func Test_ReconcileArgoCD_ReconcileRepoTLSSecret(t *testing.T) { - argocd := &v1alpha1.ArgoCD{ + argocd := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd", Namespace: "argocd-operator", @@ -209,7 +208,7 @@ func Test_ReconcileArgoCD_ReconcileRepoTLSSecret(t *testing.T) { } func Test_ReconcileArgoCD_ReconcileExistingArgoSecret(t *testing.T) { - argocd := &v1alpha1.ArgoCD{ + argocd := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd", Namespace: "argocd-operator", @@ -249,7 +248,7 @@ func Test_ReconcileArgoCD_ReconcileExistingArgoSecret(t *testing.T) { } func Test_ReconcileArgoCD_ReconcileRedisTLSSecret(t *testing.T) { - argocd := &v1alpha1.ArgoCD{ + argocd := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: "argocd", Namespace: "argocd-operator", diff --git a/controllers/argocd/service.go b/controllers/argocd/service.go index 58b8093a8..41ec3fa50 100644 --- a/controllers/argocd/service.go +++ b/controllers/argocd/service.go @@ -23,13 +23,13 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // getArgoServerServiceType will return the server Service type for the ArgoCD. -func getArgoServerServiceType(cr *argoprojv1a1.ArgoCD) corev1.ServiceType { +func getArgoServerServiceType(cr *argoproj.ArgoCD) corev1.ServiceType { if len(cr.Spec.Server.Service.Type) > 0 { return cr.Spec.Server.Service.Type } @@ -37,7 +37,7 @@ func getArgoServerServiceType(cr *argoprojv1a1.ArgoCD) corev1.ServiceType { } // newService returns a new Service for the given ArgoCD instance. -func newService(cr *argoprojv1a1.ArgoCD) *corev1.Service { +func newService(cr *argoproj.ArgoCD) *corev1.Service { return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -48,7 +48,7 @@ func newService(cr *argoprojv1a1.ArgoCD) *corev1.Service { } // newServiceWithName returns a new Service instance for the given ArgoCD using the given name. -func newServiceWithName(name string, component string, cr *argoprojv1a1.ArgoCD) *corev1.Service { +func newServiceWithName(name string, component string, cr *argoproj.ArgoCD) *corev1.Service { svc := newService(cr) svc.ObjectMeta.Name = name @@ -61,12 +61,12 @@ func newServiceWithName(name string, component string, cr *argoprojv1a1.ArgoCD) } // newServiceWithSuffix returns a new Service instance for the given ArgoCD using the given suffix. -func newServiceWithSuffix(suffix string, component string, cr *argoprojv1a1.ArgoCD) *corev1.Service { +func newServiceWithSuffix(suffix string, component string, cr *argoproj.ArgoCD) *corev1.Service { return newServiceWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), component, cr) } // reconcileGrafanaService will ensure that the Service for Grafana is present. -func (r *ReconcileArgoCD) reconcileGrafanaService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileGrafanaService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("grafana", "grafana", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { if !cr.Spec.Grafana.Enabled { @@ -102,7 +102,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaService(cr *argoprojv1a1.ArgoCD) error } // reconcileMetricsService will ensure that the Service for the Argo CD application controller metrics is present. -func (r *ReconcileArgoCD) reconcileMetricsService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileMetricsService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("metrics", "metrics", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { // Service found, do nothing @@ -129,7 +129,7 @@ func (r *ReconcileArgoCD) reconcileMetricsService(cr *argoprojv1a1.ArgoCD) error } // reconcileRedisHAAnnounceServices will ensure that the announce Services are present for Redis when running in HA mode. -func (r *ReconcileArgoCD) reconcileRedisHAAnnounceServices(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisHAAnnounceServices(cr *argoproj.ArgoCD) error { for i := int32(0); i < common.ArgoCDDefaultRedisHAReplicas; i++ { svc := newServiceWithSuffix(fmt.Sprintf("redis-ha-announce-%d", i), "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { @@ -180,7 +180,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAAnnounceServices(cr *argoprojv1a1.Argo } // reconcileRedisHAMasterService will ensure that the "master" Service is present for Redis when running in HA mode. -func (r *ReconcileArgoCD) reconcileRedisHAMasterService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisHAMasterService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("redis-ha", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { if !cr.Spec.HA.Enabled { @@ -218,7 +218,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAMasterService(cr *argoprojv1a1.ArgoCD) } // reconcileRedisHAProxyService will ensure that the HA Proxy Service is present for Redis when running in HA mode. -func (r *ReconcileArgoCD) reconcileRedisHAProxyService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisHAProxyService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("redis-ha-haproxy", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { @@ -258,7 +258,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyService(cr *argoprojv1a1.ArgoCD) } // reconcileRedisHAServices will ensure that all required Services are present for Redis when running in HA mode. -func (r *ReconcileArgoCD) reconcileRedisHAServices(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisHAServices(cr *argoproj.ArgoCD) error { if err := r.reconcileRedisHAAnnounceServices(cr); err != nil { return err @@ -275,7 +275,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAServices(cr *argoprojv1a1.ArgoCD) erro } // reconcileRedisService will ensure that the Service for Redis is present. -func (r *ReconcileArgoCD) reconcileRedisService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("redis", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { @@ -354,7 +354,7 @@ func ensureAutoTLSAnnotation(svc *corev1.Service, secretName string, enabled boo } // reconcileRepoService will ensure that the Service for the Argo CD repo server is present. -func (r *ReconcileArgoCD) reconcileRepoService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRepoService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("repo-server", "repo-server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { @@ -391,7 +391,7 @@ func (r *ReconcileArgoCD) reconcileRepoService(cr *argoprojv1a1.ArgoCD) error { } // reconcileServerMetricsService will ensure that the Service for the Argo CD server metrics is present. -func (r *ReconcileArgoCD) reconcileServerMetricsService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServerMetricsService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("server-metrics", "server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { return nil // Service found, do nothing @@ -417,7 +417,7 @@ func (r *ReconcileArgoCD) reconcileServerMetricsService(cr *argoprojv1a1.ArgoCD) } // reconcileServerService will ensure that the Service is present for the Argo CD server component. -func (r *ReconcileArgoCD) reconcileServerService(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServerService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("server", "server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { if ensureAutoTLSAnnotation(svc, common.ArgoCDServerTLSSecretName, cr.Spec.Server.WantsAutoTLS()) { @@ -455,7 +455,7 @@ func (r *ReconcileArgoCD) reconcileServerService(cr *argoprojv1a1.ArgoCD) error } // reconcileServices will ensure that all Services are present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileServices(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServices(cr *argoproj.ArgoCD) error { if err := r.reconcileDexService(cr); err != nil { log.Error(err, "error reconciling dex service") diff --git a/controllers/argocd/service_account.go b/controllers/argocd/service_account.go index b37b88f94..e7c477279 100644 --- a/controllers/argocd/service_account.go +++ b/controllers/argocd/service_account.go @@ -24,13 +24,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // newServiceAccount returns a new ServiceAccount instance. -func newServiceAccount(cr *argoprojv1a1.ArgoCD) *corev1.ServiceAccount { +func newServiceAccount(cr *argoproj.ArgoCD) *corev1.ServiceAccount { return &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -41,7 +41,7 @@ func newServiceAccount(cr *argoprojv1a1.ArgoCD) *corev1.ServiceAccount { } // newServiceAccountWithName creates a new ServiceAccount with the given name for the given ArgCD. -func newServiceAccountWithName(name string, cr *argoprojv1a1.ArgoCD) *corev1.ServiceAccount { +func newServiceAccountWithName(name string, cr *argoproj.ArgoCD) *corev1.ServiceAccount { sa := newServiceAccount(cr) sa.ObjectMeta.Name = getServiceAccountName(cr.Name, name) @@ -57,7 +57,7 @@ func getServiceAccountName(crName, name string) string { } // reconcileServiceAccounts will ensure that all ArgoCD Service Accounts are configured. -func (r *ReconcileArgoCD) reconcileServiceAccounts(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServiceAccounts(cr *argoproj.ArgoCD) error { params := getPolicyRuleList(r.Client) for _, param := range params { @@ -77,7 +77,7 @@ func (r *ReconcileArgoCD) reconcileServiceAccounts(cr *argoprojv1a1.ArgoCD) erro return nil } -func (r *ReconcileArgoCD) reconcileServiceAccountClusterPermissions(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServiceAccountClusterPermissions(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) error { var role *v1.ClusterRole var err error @@ -93,11 +93,11 @@ func (r *ReconcileArgoCD) reconcileServiceAccountClusterPermissions(name string, return r.reconcileClusterRoleBinding(name, role, cr) } -func (r *ReconcileArgoCD) reconcileServiceAccountPermissions(name string, rules []v1.PolicyRule, cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileServiceAccountPermissions(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) error { return r.reconcileRoleBinding(name, rules, cr) } -func (r *ReconcileArgoCD) reconcileServiceAccount(name string, cr *argoprojv1a1.ArgoCD) (*corev1.ServiceAccount, error) { +func (r *ReconcileArgoCD) reconcileServiceAccount(name string, cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { sa := newServiceAccountWithName(name, cr) exists := true diff --git a/controllers/argocd/sso.go b/controllers/argocd/sso.go index ee1e77122..6b3f38172 100644 --- a/controllers/argocd/sso.go +++ b/controllers/argocd/sso.go @@ -21,8 +21,7 @@ import ( template "github.com/openshift/api/template/v1" apiErrors "k8s.io/apimachinery/pkg/api/errors" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -58,7 +57,7 @@ func verifyTemplateAPI() error { // The operator must support `.spec.sso.dex` fields for dex, and `.spec.sso.keycloak` fields for keycloak. // The operator must identify edge cases involving partial configurations of specs, spec mismatch with // active provider, contradicting configuration etc, and throw the appropriate errors. -func (r *ReconcileArgoCD) reconcileSSO(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileSSO(cr *argoproj.ArgoCD) error { // reset ssoConfigLegalStatus at the beginning of each SSO reconciliation round ssoConfigLegalStatus = ssoLegalUnknown @@ -76,7 +75,7 @@ func (r *ReconcileArgoCD) reconcileSSO(cr *argoprojv1a1.ArgoCD) error { isError := false // case 2 - if cr.Spec.SSO.Provider.ToLower() == v1alpha1.SSOProviderTypeDex { + if cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeDex { // Relevant SSO settings at play are `.spec.sso.dex` fields, `.spec.sso.keycloak` if cr.Spec.SSO.Dex == nil || (cr.Spec.SSO.Dex != nil && !cr.Spec.SSO.Dex.OpenShiftOAuth && cr.Spec.SSO.Dex.Config == "") { @@ -100,7 +99,7 @@ func (r *ReconcileArgoCD) reconcileSSO(cr *argoprojv1a1.ArgoCD) error { } // case 3 - if cr.Spec.SSO.Provider.ToLower() == v1alpha1.SSOProviderTypeKeycloak { + if cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeKeycloak { // Relevant SSO settings at play are `.spec.sso.keycloak` fields, `.spec.sso.dex` if cr.Spec.SSO.Dex != nil { @@ -136,10 +135,10 @@ func (r *ReconcileArgoCD) reconcileSSO(cr *argoprojv1a1.ArgoCD) error { } // case 5 - if cr.Spec.SSO.Provider.ToLower() != v1alpha1.SSOProviderTypeDex && cr.Spec.SSO.Provider.ToLower() != v1alpha1.SSOProviderTypeKeycloak { + if cr.Spec.SSO.Provider.ToLower() != argoproj.SSOProviderTypeDex && cr.Spec.SSO.Provider.ToLower() != argoproj.SSOProviderTypeKeycloak { // `.spec.sso.provider` contains unsupported value - errMsg = fmt.Sprintf("Unsupported SSO provider type. Supported providers are %s and %s", v1alpha1.SSOProviderTypeDex, v1alpha1.SSOProviderTypeKeycloak) + errMsg = fmt.Sprintf("Unsupported SSO provider type. Supported providers are %s and %s", argoproj.SSOProviderTypeDex, argoproj.SSOProviderTypeKeycloak) err = errors.New(illegalSSOConfiguration + errMsg) log.Error(err, fmt.Sprintf("Unsupported SSO provider type for Argo CD %s in namespace %s.", cr.Name, cr.Namespace)) ssoConfigLegalStatus = ssoLegalFailed // set global indicator that SSO config has gone wrong @@ -154,7 +153,7 @@ func (r *ReconcileArgoCD) reconcileSSO(cr *argoprojv1a1.ArgoCD) error { // reconcile resources based on enabled provider // keycloak - if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoprojv1a1.SSOProviderTypeKeycloak { + if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeKeycloak { // Trigger reconciliation of any Dex resources so they get deleted if err := r.reconcileDexResources(cr); err != nil && !apiErrors.IsNotFound(err) { @@ -183,16 +182,16 @@ func (r *ReconcileArgoCD) reconcileSSO(cr *argoprojv1a1.ArgoCD) error { return nil } -func (r *ReconcileArgoCD) deleteSSOConfiguration(newCr *argoprojv1a1.ArgoCD, oldCr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) deleteSSOConfiguration(newCr *argoproj.ArgoCD, oldCr *argoproj.ArgoCD) error { log.Info("uninstalling existing SSO configuration") - if oldCr.Spec.SSO.Provider.ToLower() == argoprojv1a1.SSOProviderTypeKeycloak { + if oldCr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeKeycloak { if err := deleteKeycloakConfiguration(newCr); err != nil { log.Error(err, "Unable to delete existing keycloak configuration") return err } - } else if oldCr.Spec.SSO.Provider.ToLower() == argoprojv1a1.SSOProviderTypeDex { + } else if oldCr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeDex { // Trigger reconciliation of Dex resources so they get deleted if err := r.deleteDexResources(newCr); err != nil { log.Error(err, "Unable to reconcile necessary resources for uninstallation of Dex") diff --git a/controllers/argocd/sso_test.go b/controllers/argocd/sso_test.go index c7eed61c7..4c8f8522a 100644 --- a/controllers/argocd/sso_test.go +++ b/controllers/argocd/sso_test.go @@ -33,17 +33,16 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argov1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) -func makeFakeReconciler(t *testing.T, acd *argov1alpha1.ArgoCD, objs ...runtime.Object) *ReconcileArgoCD { +func makeFakeReconciler(t *testing.T, acd *argoproj.ArgoCD, objs ...runtime.Object) *ReconcileArgoCD { t.Helper() s := scheme.Scheme // Register template scheme s.AddKnownTypes(templatev1.SchemeGroupVersion, objs...) s.AddKnownTypes(oappsv1.SchemeGroupVersion, objs...) - assert.NoError(t, argov1alpha1.AddToScheme(s)) + assert.NoError(t, argoproj.AddToScheme(s)) templatev1.Install(s) oappsv1.Install(s) routev1.Install(s) @@ -89,23 +88,23 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { tests := []struct { name string - argoCD *argov1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantErr bool Err error wantSSOConfigLegalStatus string }{ { name: "no conflicts - no sso configured", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) {}), + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) {}), wantErr: false, wantSSOConfigLegalStatus: "Unknown", }, { name: "no conflict - case insensitive sso provider value", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "DEX", - Dex: &v1alpha1.ArgoCDDexSpec{ + Dex: &argoproj.ArgoCDDexSpec{ Config: "test-config", }, } @@ -115,10 +114,10 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "no conflict - valid dex sso configurations", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "dex", - Dex: &v1alpha1.ArgoCDDexSpec{ + Dex: &argoproj.ArgoCDDexSpec{ Config: "test-config", OpenShiftOAuth: false, }, @@ -129,8 +128,8 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "no conflict - valid keycloak sso configurations", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "keycloak", } }), @@ -139,9 +138,9 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "sso provider dex but no .spec.sso.dex provided", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, } }), wantErr: true, @@ -150,14 +149,14 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "sso provider dex + `.spec.sso.keycloak`", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Keycloak: &v1alpha1.ArgoCDKeycloakSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Keycloak: &argoproj.ArgoCDKeycloakSpec{ Image: "test-image", Version: "test-image-version", }, - Provider: argov1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Config: "test", }, } @@ -168,10 +167,10 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "sso provider keycloak + `.spec.sso.dex`", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argov1alpha1.SSOProviderTypeKeycloak, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, + Dex: &argoproj.ArgoCDDexSpec{ Config: "test-config", OpenShiftOAuth: true, }, @@ -183,13 +182,13 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "sso provider missing but sso.dex/keycloak supplied", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Dex: &argoproj.ArgoCDDexSpec{ Config: "test-config", OpenShiftOAuth: true, }, - Keycloak: &v1alpha1.ArgoCDKeycloakSpec{ + Keycloak: &argoproj.ArgoCDKeycloakSpec{ Image: "test-image", }, } @@ -200,10 +199,10 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { }, { name: "unsupported sso provider but sso.dex/keycloak supplied", - argoCD: makeTestArgoCD(func(ac *argov1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ + argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "Unsupported", - Dex: &v1alpha1.ArgoCDDexSpec{ + Dex: &argoproj.ArgoCDDexSpec{ Config: "test-config", OpenShiftOAuth: true, }, diff --git a/controllers/argocd/statefulset.go b/controllers/argocd/statefulset.go index d8d1776d3..0cefa8463 100644 --- a/controllers/argocd/statefulset.go +++ b/controllers/argocd/statefulset.go @@ -28,19 +28,19 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) -func getRedisHAReplicas(cr *argoprojv1a1.ArgoCD) *int32 { +func getRedisHAReplicas(cr *argoproj.ArgoCD) *int32 { replicas := common.ArgoCDDefaultRedisHAReplicas // TODO: Allow override of this value through CR? return &replicas } // newStatefulSet returns a new StatefulSet instance for the given ArgoCD instance. -func newStatefulSet(cr *argoprojv1a1.ArgoCD) *appsv1.StatefulSet { +func newStatefulSet(cr *argoproj.ArgoCD) *appsv1.StatefulSet { return &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -51,7 +51,7 @@ func newStatefulSet(cr *argoprojv1a1.ArgoCD) *appsv1.StatefulSet { } // newStatefulSetWithName returns a new StatefulSet instance for the given ArgoCD using the given name. -func newStatefulSetWithName(name string, component string, cr *argoprojv1a1.ArgoCD) *appsv1.StatefulSet { +func newStatefulSetWithName(name string, component string, cr *argoproj.ArgoCD) *appsv1.StatefulSet { ss := newStatefulSet(cr) ss.ObjectMeta.Name = name @@ -87,11 +87,11 @@ func newStatefulSetWithName(name string, component string, cr *argoprojv1a1.Argo } // newStatefulSetWithSuffix returns a new StatefulSet instance for the given ArgoCD using the given suffix. -func newStatefulSetWithSuffix(suffix string, component string, cr *argoprojv1a1.ArgoCD) *appsv1.StatefulSet { +func newStatefulSetWithSuffix(suffix string, component string, cr *argoproj.ArgoCD) *appsv1.StatefulSet { return newStatefulSetWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), component, cr) } -func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoproj.ArgoCD) error { ss := newStatefulSetWithSuffix("redis-ha-server", "redis", cr) ss.Spec.PodManagementPolicy = appsv1.OrderedReadyPodManagement @@ -434,7 +434,7 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoprojv1a1.ArgoCD) err return r.Client.Create(context.TODO(), ss) } -func getArgoControllerContainerEnv(cr *argoprojv1a1.ArgoCD) []corev1.EnvVar { +func getArgoControllerContainerEnv(cr *argoproj.ArgoCD) []corev1.EnvVar { env := make([]corev1.EnvVar, 0) env = append(env, corev1.EnvVar{ @@ -459,7 +459,7 @@ func getArgoControllerContainerEnv(cr *argoprojv1a1.ArgoCD) []corev1.EnvVar { return env } -func (r *ReconcileArgoCD) getApplicationControllerReplicaCount(cr *argoprojv1a1.ArgoCD) int32 { +func (r *ReconcileArgoCD) getApplicationControllerReplicaCount(cr *argoproj.ArgoCD) int32 { var replicas int32 = common.ArgocdApplicationControllerDefaultReplicas var minShards int32 = cr.Spec.Controller.Sharding.MinShards var maxShards int32 = cr.Spec.Controller.Sharding.MaxShards @@ -509,7 +509,7 @@ func (r *ReconcileArgoCD) getApplicationControllerReplicaCount(cr *argoprojv1a1. return replicas } -func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj.ArgoCD, useTLSForRedis bool) error { replicas := r.getApplicationControllerReplicaCount(cr) @@ -711,7 +711,7 @@ func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj } // reconcileStatefulSets will ensure that all StatefulSets are present for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatefulSets(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) error { +func (r *ReconcileArgoCD) reconcileStatefulSets(cr *argoproj.ArgoCD, useTLSForRedis bool) error { if err := r.reconcileApplicationControllerStatefulSet(cr, useTLSForRedis); err != nil { return err } @@ -746,7 +746,7 @@ func updateNodePlacementStateful(existing *appsv1.StatefulSet, ss *appsv1.Statef // Returns true if a StatefulSet has pods in ErrImagePull or ImagePullBackoff state. // These pods cannot be restarted automatially due to known kubernetes issue https://github.com/kubernetes/kubernetes/issues/67250 -func containsInvalidImage(cr *argoprojv1a1.ArgoCD, r *ReconcileArgoCD) bool { +func containsInvalidImage(cr *argoproj.ArgoCD, r *ReconcileArgoCD) bool { brokenPod := false diff --git a/controllers/argocd/statefulset_test.go b/controllers/argocd/statefulset_test.go index 4a454b4ee..4157cbcfe 100644 --- a/controllers/argocd/statefulset_test.go +++ b/controllers/argocd/statefulset_test.go @@ -11,6 +11,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" "github.com/google/go-cmp/cmp" @@ -238,8 +239,8 @@ func TestReconcileArgoCD_reconcileApplicationController_withUpgrade(t *testing.T func TestReconcileArgoCD_reconcileApplicationController_withResources(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCDWithResources(func(a *argoprojv1alpha1.ArgoCD) { - a.Spec.Import = &argoprojv1alpha1.ArgoCDImportSpec{ + a := makeTestArgoCDWithResources(func(a *argoproj.ArgoCD) { + a.Spec.Import = &argoproj.ArgoCDImportSpec{ Name: "testimport", } }) @@ -302,12 +303,12 @@ func TestReconcileArgoCD_reconcileApplicationController_withSharding(t *testing. logf.SetLogger(ZapLogger(true)) tests := []struct { - sharding argoprojv1alpha1.ArgoCDApplicationControllerShardSpec + sharding argoproj.ArgoCDApplicationControllerShardSpec replicas int32 vars []corev1.EnvVar }{ { - sharding: argoprojv1alpha1.ArgoCDApplicationControllerShardSpec{ + sharding: argoproj.ArgoCDApplicationControllerShardSpec{ Enabled: false, Replicas: 3, }, @@ -317,7 +318,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withSharding(t *testing. }, }, { - sharding: argoprojv1alpha1.ArgoCDApplicationControllerShardSpec{ + sharding: argoproj.ArgoCDApplicationControllerShardSpec{ Enabled: true, Replicas: 1, }, @@ -328,7 +329,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withSharding(t *testing. }, }, { - sharding: argoprojv1alpha1.ArgoCDApplicationControllerShardSpec{ + sharding: argoproj.ArgoCDApplicationControllerShardSpec{ Enabled: true, Replicas: 3, }, @@ -341,7 +342,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withSharding(t *testing. } for _, st := range tests { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Controller.Sharding = st.sharding }) r := makeTestReconciler(t, a) @@ -380,7 +381,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withAppSync(t *testing.T {Name: "HOME", Value: "/home/argocd"}, } - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Controller.AppSync = &metav1.Duration{Duration: time.Minute * 10} }) r := makeTestReconciler(t, a) @@ -489,12 +490,12 @@ func TestReconcileArgoCD_reconcileApplicationController_withDynamicSharding(t *t logf.SetLogger(ZapLogger(true)) tests := []struct { - sharding argoprojv1alpha1.ArgoCDApplicationControllerShardSpec + sharding argoproj.ArgoCDApplicationControllerShardSpec expectedReplicas int32 vars []corev1.EnvVar }{ { - sharding: argoprojv1alpha1.ArgoCDApplicationControllerShardSpec{ + sharding: argoproj.ArgoCDApplicationControllerShardSpec{ Enabled: false, Replicas: 1, DynamicScalingEnabled: boolPtr(true), @@ -506,7 +507,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withDynamicSharding(t *t }, { // Replicas less than minimum shards - sharding: argoprojv1alpha1.ArgoCDApplicationControllerShardSpec{ + sharding: argoproj.ArgoCDApplicationControllerShardSpec{ Enabled: false, Replicas: 1, DynamicScalingEnabled: boolPtr(true), @@ -518,7 +519,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withDynamicSharding(t *t }, { // Replicas more than maximum shards - sharding: argoprojv1alpha1.ArgoCDApplicationControllerShardSpec{ + sharding: argoproj.ArgoCDApplicationControllerShardSpec{ Enabled: false, Replicas: 1, DynamicScalingEnabled: boolPtr(true), @@ -531,7 +532,7 @@ func TestReconcileArgoCD_reconcileApplicationController_withDynamicSharding(t *t } for _, st := range tests { - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Controller.Sharding = st.sharding }) diff --git a/controllers/argocd/status.go b/controllers/argocd/status.go index da3e5f683..ae7aee3be 100644 --- a/controllers/argocd/status.go +++ b/controllers/argocd/status.go @@ -26,12 +26,12 @@ import ( "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // reconcileStatus will ensure that all of the Status properties are updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatus(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatus(cr *argoproj.ArgoCD) error { if err := r.reconcileStatusApplicationController(cr); err != nil { return err } @@ -72,7 +72,7 @@ func (r *ReconcileArgoCD) reconcileStatus(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusApplicationController will ensure that the ApplicationController Status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusApplicationController(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusApplicationController(cr *argoproj.ArgoCD) error { status := "Unknown" ss := newStatefulSetWithSuffix("application-controller", "application-controller", cr) @@ -94,7 +94,7 @@ func (r *ReconcileArgoCD) reconcileStatusApplicationController(cr *argoprojv1a1. } // reconcileStatusDex will ensure that the Dex status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusDex(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusDex(cr *argoproj.ArgoCD) error { status := "Unknown" deploy := newDeploymentWithSuffix("dex-server", "dex-server", cr) @@ -117,7 +117,7 @@ func (r *ReconcileArgoCD) reconcileStatusDex(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusKeycloak will ensure that the Keycloak status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusKeycloak(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusKeycloak(cr *argoproj.ArgoCD) error { status := "Unknown" if IsTemplateAPIAvailable() { @@ -158,7 +158,7 @@ func (r *ReconcileArgoCD) reconcileStatusKeycloak(cr *argoprojv1a1.ArgoCD) error } // reconcileStatusApplicationSetController will ensure that the ApplicationSet controller status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusApplicationSetController(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusApplicationSetController(cr *argoproj.ArgoCD) error { status := "Unknown" deploy := newDeploymentWithSuffix("applicationset-controller", "controller", cr) @@ -180,16 +180,16 @@ func (r *ReconcileArgoCD) reconcileStatusApplicationSetController(cr *argoprojv1 } // reconcileStatusSSOConfig will ensure that the SSOConfig status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusSSO(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusSSO(cr *argoproj.ArgoCD) error { // set status to track ssoConfigLegalStatus so it is always up to date with latest sso situation status := ssoConfigLegalStatus // perform dex/keycloak status reconciliation only if sso configurations are legal if status == ssoLegalSuccess { - if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoprojv1a1.SSOProviderTypeDex { + if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeDex { return r.reconcileStatusDex(cr) - } else if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoprojv1a1.SSOProviderTypeKeycloak { + } else if cr.Spec.SSO != nil && cr.Spec.SSO.Provider.ToLower() == argoproj.SSOProviderTypeKeycloak { return r.reconcileStatusKeycloak(cr) } } else { @@ -204,7 +204,7 @@ func (r *ReconcileArgoCD) reconcileStatusSSO(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusPhase will ensure that the Status Phase is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusPhase(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusPhase(cr *argoproj.ArgoCD) error { var phase string if cr.Status.ApplicationController == "Running" && cr.Status.Redis == "Running" && cr.Status.Repo == "Running" && cr.Status.Server == "Running" { @@ -221,7 +221,7 @@ func (r *ReconcileArgoCD) reconcileStatusPhase(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusRedis will ensure that the Redis status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusRedis(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusRedis(cr *argoproj.ArgoCD) error { status := "Unknown" if !cr.Spec.HA.Enabled { @@ -255,7 +255,7 @@ func (r *ReconcileArgoCD) reconcileStatusRedis(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusRepo will ensure that the Repo status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoproj.ArgoCD) error { status := "Unknown" deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) @@ -277,7 +277,7 @@ func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusServer will ensure that the Server status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusServer(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusServer(cr *argoproj.ArgoCD) error { status := "Unknown" deploy := newDeploymentWithSuffix("server", "server", cr) @@ -300,7 +300,7 @@ func (r *ReconcileArgoCD) reconcileStatusServer(cr *argoprojv1a1.ArgoCD) error { } // reconcileStatusNotifications will ensure that the Notifications status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusNotifications(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusNotifications(cr *argoproj.ArgoCD) error { status := "Unknown" deploy := newDeploymentWithSuffix("notifications-controller", "controller", cr) @@ -326,7 +326,7 @@ func (r *ReconcileArgoCD) reconcileStatusNotifications(cr *argoprojv1a1.ArgoCD) } // reconcileStatusHost will ensure that the host status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileStatusHost(cr *argoproj.ArgoCD) error { cr.Status.Host = "" if (cr.Spec.Server.Route.Enabled || cr.Spec.Server.Ingress.Enabled) && IsRouteAPIAvailable() { diff --git a/controllers/argocd/status_test.go b/controllers/argocd/status_test.go index 5c736038d..b045b94c0 100644 --- a/controllers/argocd/status_test.go +++ b/controllers/argocd/status_test.go @@ -4,8 +4,7 @@ import ( "context" "testing" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" oappsv1 "github.com/openshift/api/apps/v1" routev1 "github.com/openshift/api/route/v1" @@ -81,15 +80,15 @@ func TestReconcileArgoCD_reconcileStatusSSO(t *testing.T) { tests := []struct { name string - argoCD *argoprojv1alpha1.ArgoCD + argoCD *argoproj.ArgoCD wantSSOStatus string }{ { name: "both dex and keycloak configured", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeKeycloak, - Dex: &v1alpha1.ArgoCDDexSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeKeycloak, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -98,26 +97,26 @@ func TestReconcileArgoCD_reconcileStatusSSO(t *testing.T) { }, { name: "sso provider dex but no .spec.sso.dex provided", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: argoprojv1alpha1.SSOProviderTypeDex, + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, } }), wantSSOStatus: "Failed", }, { name: "no sso configured", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { cr.Spec.SSO = nil }), wantSSOStatus: "Unknown", }, { name: "unsupported sso configured", - argoCD: makeTestArgoCD(func(cr *argoprojv1alpha1.ArgoCD) { - cr.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: "Unsupported", - Dex: &v1alpha1.ArgoCDDexSpec{ + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } @@ -175,7 +174,7 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { routeAPIFound = test.testRouteAPIFound - a := makeTestArgoCD(func(a *argoprojv1alpha1.ArgoCD) { + a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Route.Enabled = test.routeEnabled a.Spec.Server.Ingress.Enabled = test.ingressEnabled }) @@ -278,7 +277,7 @@ func TestReconcileArgoCD_reconcileStatusApplicationSetController(t *testing.T) { assert.NoError(t, r.reconcileStatusApplicationSetController(a)) assert.Equal(t, "Unknown", a.Status.ApplicationSetController) - a.Spec.ApplicationSet = &v1alpha1.ArgoCDApplicationSet{} + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} assert.NoError(t, r.reconcileApplicationSetController(a)) assert.NoError(t, r.reconcileStatusApplicationSetController(a)) assert.Equal(t, "Pending", a.Status.ApplicationSetController) diff --git a/controllers/argocd/testing.go b/controllers/argocd/testing.go index 95c884a63..7c33d49f1 100644 --- a/controllers/argocd/testing.go +++ b/controllers/argocd/testing.go @@ -37,6 +37,7 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argoutil" argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) const ( @@ -51,6 +52,7 @@ func ZapLogger(development bool) logr.Logger { func makeTestReconciler(t *testing.T, objs ...runtime.Object) *ReconcileArgoCD { s := scheme.Scheme + assert.NoError(t, argoproj.AddToScheme(s)) assert.NoError(t, argoprojv1alpha1.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() @@ -60,10 +62,10 @@ func makeTestReconciler(t *testing.T, objs ...runtime.Object) *ReconcileArgoCD { } } -type argoCDOpt func(*argoprojv1alpha1.ArgoCD) +type argoCDOpt func(*argoproj.ArgoCD) -func makeTestArgoCD(opts ...argoCDOpt) *argoprojv1alpha1.ArgoCD { - a := &argoprojv1alpha1.ArgoCD{ +func makeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { + a := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: testArgoCDName, Namespace: testNamespace, @@ -75,18 +77,18 @@ func makeTestArgoCD(opts ...argoCDOpt) *argoprojv1alpha1.ArgoCD { return a } -func makeTestArgoCDForKeycloak() *argoprojv1alpha1.ArgoCD { - a := &argoprojv1alpha1.ArgoCD{ +func makeTestArgoCDForKeycloak() *argoproj.ArgoCD { + a := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: testArgoCDName, Namespace: testNamespace, }, - Spec: argoprojv1alpha1.ArgoCDSpec{ - SSO: &argoprojv1alpha1.ArgoCDSSOSpec{ + Spec: argoproj.ArgoCDSpec{ + SSO: &argoproj.ArgoCDSSOSpec{ Provider: "keycloak", }, - Server: argoprojv1alpha1.ArgoCDServerSpec{ - Route: argoprojv1alpha1.ArgoCDRouteSpec{ + Server: argoproj.ArgoCDServerSpec{ + Route: argoproj.ArgoCDRouteSpec{ Enabled: true, }, }, @@ -95,26 +97,26 @@ func makeTestArgoCDForKeycloak() *argoprojv1alpha1.ArgoCD { return a } -func makeTestArgoCDWithResources(opts ...argoCDOpt) *argoprojv1alpha1.ArgoCD { - a := &argoprojv1alpha1.ArgoCD{ +func makeTestArgoCDWithResources(opts ...argoCDOpt) *argoproj.ArgoCD { + a := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ Name: testArgoCDName, Namespace: testNamespace, }, - Spec: argoprojv1alpha1.ArgoCDSpec{ - ApplicationSet: &argoprojv1alpha1.ArgoCDApplicationSet{ + Spec: argoproj.ArgoCDSpec{ + ApplicationSet: &argoproj.ArgoCDApplicationSet{ Resources: makeTestApplicationSetResources(), }, - HA: argoprojv1alpha1.ArgoCDHASpec{ + HA: argoproj.ArgoCDHASpec{ Resources: makeTestHAResources(), }, - SSO: &argoprojv1alpha1.ArgoCDSSOSpec{ + SSO: &argoproj.ArgoCDSSOSpec{ Provider: "dex", - Dex: &argoprojv1alpha1.ArgoCDDexSpec{ + Dex: &argoproj.ArgoCDDexSpec{ Resources: makeTestDexResources(), }, }, - Controller: argoprojv1alpha1.ArgoCDApplicationControllerSpec{ + Controller: argoproj.ArgoCDApplicationControllerSpec{ Resources: makeTestControllerResources(), }, }, @@ -181,7 +183,7 @@ func makeTestPolicyRules() []v1.PolicyRule { func initialCerts(t *testing.T, host string) argoCDOpt { t.Helper() - return func(a *argoprojv1alpha1.ArgoCD) { + return func(a *argoproj.ArgoCD) { key, err := argoutil.NewPrivateKey() assert.NoError(t, err) cert, err := argoutil.NewSelfSignedCACertificate(a.Name, key) diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index 1050f4237..6cb1dad4d 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -31,8 +31,7 @@ import ( "gopkg.in/yaml.v2" - argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" @@ -105,7 +104,7 @@ func generateArgoServerSessionKey() ([]byte, error) { } // getArgoApplicationControllerResources will return the ResourceRequirements for the Argo CD application controller container. -func getArgoApplicationControllerResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getArgoApplicationControllerResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR @@ -117,7 +116,7 @@ func getArgoApplicationControllerResources(cr *argoprojv1a1.ArgoCD) corev1.Resou } // getArgoApplicationControllerCommand will return the command for the ArgoCD Application Controller component. -func getArgoApplicationControllerCommand(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) []string { +func getArgoApplicationControllerCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { cmd := []string{ "argocd-application-controller", "--operation-processors", fmt.Sprint(getArgoServerOperationProcessors(cr)), @@ -151,7 +150,7 @@ func getArgoApplicationControllerCommand(cr *argoprojv1a1.ArgoCD, useTLSForRedis } // getArgoContainerImage will return the container image for ArgoCD. -func getArgoContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getArgoContainerImage(cr *argoproj.ArgoCD) string { defaultTag, defaultImg := false, false img := cr.Spec.Image if img == "" { @@ -182,7 +181,7 @@ func getArgoContainerImage(cr *argoprojv1a1.ArgoCD) string { // that if the spec is not configured. // 3. the default is configured in common.ArgoCDDefaultRepoServerVersion and // common.ArgoCDDefaultRepoServerImage. -func getRepoServerContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getRepoServerContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := cr.Spec.Repo.Image if img == "" { @@ -202,7 +201,7 @@ func getRepoServerContainerImage(cr *argoprojv1a1.ArgoCD) string { } // getArgoRepoResources will return the ResourceRequirements for the Argo CD Repo server container. -func getArgoRepoResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getArgoRepoResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR @@ -214,20 +213,20 @@ func getArgoRepoResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { } // getArgoServerInsecure returns the insecure value for the ArgoCD Server component. -func getArgoServerInsecure(cr *argoprojv1a1.ArgoCD) bool { +func getArgoServerInsecure(cr *argoproj.ArgoCD) bool { return cr.Spec.Server.Insecure } -func isRepoServerTLSVerificationRequested(cr *argoprojv1a1.ArgoCD) bool { +func isRepoServerTLSVerificationRequested(cr *argoproj.ArgoCD) bool { return cr.Spec.Repo.VerifyTLS } -func isRedisTLSVerificationDisabled(cr *argoprojv1a1.ArgoCD) bool { +func isRedisTLSVerificationDisabled(cr *argoproj.ArgoCD) bool { return cr.Spec.Redis.DisableTLSVerification } // getArgoServerGRPCHost will return the GRPC host for the given ArgoCD. -func getArgoServerGRPCHost(cr *argoprojv1a1.ArgoCD) string { +func getArgoServerGRPCHost(cr *argoproj.ArgoCD) string { host := nameWithSuffix("grpc", cr) if len(cr.Spec.Server.GRPC.Host) > 0 { host = cr.Spec.Server.GRPC.Host @@ -236,7 +235,7 @@ func getArgoServerGRPCHost(cr *argoprojv1a1.ArgoCD) string { } // getArgoServerHost will return the host for the given ArgoCD. -func getArgoServerHost(cr *argoprojv1a1.ArgoCD) string { +func getArgoServerHost(cr *argoproj.ArgoCD) string { host := cr.Name if len(cr.Spec.Server.Host) > 0 { host = cr.Spec.Server.Host @@ -245,7 +244,7 @@ func getArgoServerHost(cr *argoprojv1a1.ArgoCD) string { } // getArgoServerResources will return the ResourceRequirements for the Argo CD server container. -func getArgoServerResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getArgoServerResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} if cr.Spec.Server.Autoscale.Enabled { @@ -271,7 +270,7 @@ func getArgoServerResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements // getArgoServerURI will return the URI for the ArgoCD server. // The hostname for argocd-server is from the route, ingress, an external hostname or service name in that order. -func (r *ReconcileArgoCD) getArgoServerURI(cr *argoprojv1a1.ArgoCD) string { +func (r *ReconcileArgoCD) getArgoServerURI(cr *argoproj.ArgoCD) string { host := nameWithSuffix("server", cr) // Default to service name // Use the external hostname provided by the user @@ -299,7 +298,7 @@ func (r *ReconcileArgoCD) getArgoServerURI(cr *argoprojv1a1.ArgoCD) string { } // getArgoServerOperationProcessors will return the numeric Operation Processors value for the ArgoCD Server. -func getArgoServerOperationProcessors(cr *argoprojv1a1.ArgoCD) int32 { +func getArgoServerOperationProcessors(cr *argoproj.ArgoCD) int32 { op := common.ArgoCDDefaultServerOperationProcessors if cr.Spec.Controller.Processors.Operation > op { op = cr.Spec.Controller.Processors.Operation @@ -308,7 +307,7 @@ func getArgoServerOperationProcessors(cr *argoprojv1a1.ArgoCD) int32 { } // getArgoServerStatusProcessors will return the numeric Status Processors value for the ArgoCD Server. -func getArgoServerStatusProcessors(cr *argoprojv1a1.ArgoCD) int32 { +func getArgoServerStatusProcessors(cr *argoproj.ArgoCD) int32 { sp := common.ArgoCDDefaultServerStatusProcessors if cr.Spec.Controller.Processors.Status > sp { sp = cr.Spec.Controller.Processors.Status @@ -317,7 +316,7 @@ func getArgoServerStatusProcessors(cr *argoprojv1a1.ArgoCD) int32 { } // getArgoControllerParellismLimit returns the parallelism limit for the application controller -func getArgoControllerParellismLimit(cr *argoprojv1a1.ArgoCD) int32 { +func getArgoControllerParellismLimit(cr *argoproj.ArgoCD) int32 { pl := common.ArgoCDDefaultControllerParallelismLimit if cr.Spec.Controller.ParallelismLimit > 0 { pl = cr.Spec.Controller.ParallelismLimit @@ -326,7 +325,7 @@ func getArgoControllerParellismLimit(cr *argoprojv1a1.ArgoCD) int32 { } // getGrafanaContainerImage will return the container image for the Grafana server. -func getGrafanaContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getGrafanaContainerImage(cr *argoproj.ArgoCD) string { defaultTag, defaultImg := false, false img := cr.Spec.Grafana.Image if img == "" { @@ -346,7 +345,7 @@ func getGrafanaContainerImage(cr *argoprojv1a1.ArgoCD) string { } // getGrafanaResources will return the ResourceRequirements for the Grafana container. -func getGrafanaResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getGrafanaResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR @@ -382,7 +381,7 @@ func getRedisConf(useTLSForRedis bool) string { } // getRedisContainerImage will return the container image for the Redis server. -func getRedisContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getRedisContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := cr.Spec.Redis.Image if img == "" { @@ -401,7 +400,7 @@ func getRedisContainerImage(cr *argoprojv1a1.ArgoCD) string { } // getRedisHAContainerImage will return the container image for the Redis server in HA mode. -func getRedisHAContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getRedisHAContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := cr.Spec.Redis.Image if img == "" { @@ -420,12 +419,12 @@ func getRedisHAContainerImage(cr *argoprojv1a1.ArgoCD) string { } // getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. -func getRedisHAProxyAddress(cr *argoprojv1a1.ArgoCD) string { +func getRedisHAProxyAddress(cr *argoproj.ArgoCD) string { return fqdnServiceRef("redis-ha-haproxy", common.ArgoCDDefaultRedisPort, cr) } // getRedisHAProxyContainerImage will return the container image for the Redis HA Proxy. -func getRedisHAProxyContainerImage(cr *argoprojv1a1.ArgoCD) string { +func getRedisHAProxyContainerImage(cr *argoproj.ArgoCD) string { defaultImg, defaultTag := false, false img := cr.Spec.HA.RedisProxyImage if len(img) <= 0 { @@ -448,7 +447,7 @@ func getRedisHAProxyContainerImage(cr *argoprojv1a1.ArgoCD) string { // getRedisInitScript will load the redis init script from a template on disk for the given ArgoCD. // If an error occurs, an empty string value will be returned. -func getRedisInitScript(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) string { +func getRedisInitScript(cr *argoproj.ArgoCD, useTLSForRedis bool) string { path := fmt.Sprintf("%s/init.sh.tpl", getRedisConfigPath()) vars := map[string]string{ "ServiceName": nameWithSuffix("redis-ha", cr), @@ -465,7 +464,7 @@ func getRedisInitScript(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) string { // getRedisHAProxySConfig will load the Redis HA Proxy configuration from a template on disk for the given ArgoCD. // If an error occurs, an empty string value will be returned. -func getRedisHAProxyConfig(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) string { +func getRedisHAProxyConfig(cr *argoproj.ArgoCD, useTLSForRedis bool) string { path := fmt.Sprintf("%s/haproxy.cfg.tpl", getRedisConfigPath()) vars := map[string]string{ "ServiceName": nameWithSuffix("redis-ha", cr), @@ -482,7 +481,7 @@ func getRedisHAProxyConfig(cr *argoprojv1a1.ArgoCD, useTLSForRedis bool) string // getRedisHAProxyScript will load the Redis HA Proxy init script from a template on disk for the given ArgoCD. // If an error occurs, an empty string value will be returned. -func getRedisHAProxyScript(cr *argoprojv1a1.ArgoCD) string { +func getRedisHAProxyScript(cr *argoproj.ArgoCD) string { path := fmt.Sprintf("%s/haproxy_init.sh.tpl", getRedisConfigPath()) vars := map[string]string{ "ServiceName": nameWithSuffix("redis-ha", cr), @@ -497,7 +496,7 @@ func getRedisHAProxyScript(cr *argoprojv1a1.ArgoCD) string { } // getRedisResources will return the ResourceRequirements for the Redis container. -func getRedisResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getRedisResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR @@ -509,7 +508,7 @@ func getRedisResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { } // getRedisHAResources will return the ResourceRequirements for the Redis HA. -func getRedisHAResources(cr *argoprojv1a1.ArgoCD) corev1.ResourceRequirements { +func getRedisHAResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { resources := corev1.ResourceRequirements{} // Allow override of resource requirements from CR @@ -581,7 +580,7 @@ func getSentinelLivenessScript(useTLSForRedis bool) string { } // getRedisServerAddress will return the Redis service address for the given ArgoCD. -func getRedisServerAddress(cr *argoprojv1a1.ArgoCD) string { +func getRedisServerAddress(cr *argoproj.ArgoCD) string { if cr.Spec.HA.Enabled { return getRedisHAProxyAddress(cr) } @@ -608,13 +607,13 @@ func loadTemplateFile(path string, params map[string]string) (string, error) { // nameWithSuffix will return a name based on the given ArgoCD. The given suffix is appended to the generated name. // Example: Given an ArgoCD with the name "example-argocd", providing the suffix "foo" would result in the value of // "example-argocd-foo" being returned. -func nameWithSuffix(suffix string, cr *argoprojv1a1.ArgoCD) string { +func nameWithSuffix(suffix string, cr *argoproj.ArgoCD) string { return fmt.Sprintf("%s-%s", cr.Name, suffix) } // fqdnServiceRef will return the FQDN referencing a specific service name, as set up by the operator, with the // given port. -func fqdnServiceRef(service string, port int, cr *argoprojv1a1.ArgoCD) string { +func fqdnServiceRef(service string, port int, cr *argoproj.ArgoCD) string { return fmt.Sprintf("%s.%s.svc.cluster.local:%d", nameWithSuffix(service, cr), cr.Namespace, port) } @@ -640,7 +639,7 @@ func InspectCluster() error { } // reconcileCertificateAuthority will reconcile all Certificate Authority resources. -func (r *ReconcileArgoCD) reconcileCertificateAuthority(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileCertificateAuthority(cr *argoproj.ArgoCD) error { log.Info("reconciling CA secret") if err := r.reconcileClusterCASecret(cr); err != nil { return err @@ -653,7 +652,7 @@ func (r *ReconcileArgoCD) reconcileCertificateAuthority(cr *argoprojv1a1.ArgoCD) return nil } -func (r *ReconcileArgoCD) redisShouldUseTLS(cr *argoprojv1a1.ArgoCD) bool { +func (r *ReconcileArgoCD) redisShouldUseTLS(cr *argoproj.ArgoCD) bool { var tlsSecretObj corev1.Secret tlsSecretName := types.NamespacedName{Namespace: cr.Namespace, Name: common.ArgoCDRedisServerTLSSecretName} err := r.Client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) @@ -703,7 +702,7 @@ func (r *ReconcileArgoCD) redisShouldUseTLS(cr *argoprojv1a1.ArgoCD) bool { } // reconcileResources will reconcile common ArgoCD resources. -func (r *ReconcileArgoCD) reconcileResources(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) reconcileResources(cr *argoproj.ArgoCD) error { // we reconcile SSO first so that we can catch and throw errors for any illegal SSO configurations right away, and return control from here // preventing dex resources from getting created anyway through the other function calls, effectively bypassing the SSO checks @@ -833,7 +832,7 @@ func (r *ReconcileArgoCD) reconcileResources(cr *argoprojv1a1.ArgoCD) error { return nil } -func (r *ReconcileArgoCD) deleteClusterResources(cr *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) deleteClusterResources(cr *argoproj.ArgoCD) error { selector, err := argocdInstanceSelector(cr.Name) if err != nil { return err @@ -904,7 +903,7 @@ func argocdInstanceSelector(name string) (labels.Selector, error) { return selector.Add(*requirement), nil } -func (r *ReconcileArgoCD) removeDeletionFinalizer(argocd *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) removeDeletionFinalizer(argocd *argoproj.ArgoCD) error { argocd.Finalizers = removeString(argocd.GetFinalizers(), common.ArgoCDDeletionFinalizer) if err := r.Client.Update(context.TODO(), argocd); err != nil { return fmt.Errorf("failed to remove deletion finalizer from %s: %w", argocd.Name, err) @@ -912,7 +911,7 @@ func (r *ReconcileArgoCD) removeDeletionFinalizer(argocd *argoprojv1a1.ArgoCD) e return nil } -func (r *ReconcileArgoCD) addDeletionFinalizer(argocd *argoprojv1a1.ArgoCD) error { +func (r *ReconcileArgoCD) addDeletionFinalizer(argocd *argoproj.ArgoCD) error { argocd.Finalizers = append(argocd.Finalizers, common.ArgoCDDeletionFinalizer) if err := r.Client.Update(context.TODO(), argocd); err != nil { return fmt.Errorf("failed to add deletion finalizer for %s: %w", argocd.Name, err) @@ -968,11 +967,11 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou deleteSSOPred := predicate.Funcs{ UpdateFunc: func(e event.UpdateEvent) bool { - newCR, ok := e.ObjectNew.(*argoprojv1a1.ArgoCD) + newCR, ok := e.ObjectNew.(*argoproj.ArgoCD) if !ok { return false } - oldCR, ok := e.ObjectOld.(*argoprojv1a1.ArgoCD) + oldCR, ok := e.ObjectOld.(*argoproj.ArgoCD) if !ok { return false } @@ -1002,11 +1001,11 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou // field. When a change is detected that results in notifications being disabled, we trigger deletion of notifications resources deleteNotificationsPred := predicate.Funcs{ UpdateFunc: func(e event.UpdateEvent) bool { - newCR, ok := e.ObjectNew.(*argoprojv1a1.ArgoCD) + newCR, ok := e.ObjectNew.(*argoproj.ArgoCD) if !ok { return false } - oldCR, ok := e.ObjectOld.(*argoprojv1a1.ArgoCD) + oldCR, ok := e.ObjectOld.(*argoproj.ArgoCD) if !ok { return false } @@ -1022,7 +1021,7 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou } // Watch for changes to primary resource ArgoCD - bldr.For(&argoprojv1a1.ArgoCD{}, builder.WithPredicates(deleteSSOPred, deleteNotificationsPred)) + bldr.For(&argoproj.ArgoCD{}, builder.WithPredicates(deleteSSOPred, deleteNotificationsPred)) // Watch for changes to ConfigMap sub-resources owned by ArgoCD instances. bldr.Owns(&corev1.ConfigMap{}) @@ -1088,7 +1087,7 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou // Watch for the changes to Deployment Config bldr.Watches(&source.Kind{Type: &oappsv1.DeploymentConfig{}}, &handler.EnqueueRequestForOwner{ IsController: true, - OwnerType: &argoprojv1a1.ArgoCD{}, + OwnerType: &argoproj.ArgoCD{}, }, builder.WithPredicates(deploymentConfigPred)) } @@ -1591,7 +1590,7 @@ func contains(s []string, g string) bool { } // getApplicationSetHTTPServerHost will return the host for the given ArgoCD. -func getApplicationSetHTTPServerHost(cr *argoprojv1a1.ArgoCD) string { +func getApplicationSetHTTPServerHost(cr *argoproj.ArgoCD) string { host := cr.Name if len(cr.Spec.ApplicationSet.WebhookServer.Host) > 0 { host = cr.Spec.ApplicationSet.WebhookServer.Host diff --git a/controllers/argocd/util_test.go b/controllers/argocd/util_test.go index 61641a08b..d028dc74f 100644 --- a/controllers/argocd/util_test.go +++ b/controllers/argocd/util_test.go @@ -10,8 +10,7 @@ import ( "github.com/stretchr/testify/assert" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" @@ -34,7 +33,7 @@ var imageTests = []struct { pre func(t *testing.T) opts []argoCDOpt want string - imageFunc func(a *argoprojv1alpha1.ArgoCD) string + imageFunc func(a *argoproj.ArgoCD) string }{ { name: "dex default configuration", @@ -45,10 +44,10 @@ var imageTests = []struct { name: "dex spec configuration", imageFunc: getDexContainerImage, want: dexTestImage, - opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { - a.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + opts: []argoCDOpt{func(a *argoproj.ArgoCD) { + a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ Image: "testing/dex", Version: "latest", }, @@ -71,7 +70,7 @@ var imageTests = []struct { { name: "argo spec configuration", imageFunc: getArgoContainerImage, - want: argoTestImage, opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { + want: argoTestImage, opts: []argoCDOpt{func(a *argoproj.ArgoCD) { a.Spec.Image = "testing/argocd" a.Spec.Version = "latest" }}, @@ -93,7 +92,7 @@ var imageTests = []struct { name: "grafana spec configuration", imageFunc: getGrafanaContainerImage, want: grafanaTestImage, - opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { + opts: []argoCDOpt{func(a *argoproj.ArgoCD) { a.Spec.Grafana.Image = "testing/grafana" a.Spec.Grafana.Version = "latest" }}, @@ -115,7 +114,7 @@ var imageTests = []struct { name: "redis spec configuration", imageFunc: getRedisContainerImage, want: redisTestImage, - opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { + opts: []argoCDOpt{func(a *argoproj.ArgoCD) { a.Spec.Redis.Image = "testing/redis" a.Spec.Redis.Version = "latest" }}, @@ -139,7 +138,7 @@ var imageTests = []struct { name: "redis ha spec configuration", imageFunc: getRedisHAContainerImage, want: redisHATestImage, - opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { + opts: []argoCDOpt{func(a *argoproj.ArgoCD) { a.Spec.Redis.Image = "testing/redis" a.Spec.Redis.Version = "latest-ha" }}, @@ -163,7 +162,7 @@ var imageTests = []struct { name: "redis ha proxy spec configuration", imageFunc: getRedisHAProxyContainerImage, want: redisHAProxyTestImage, - opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { + opts: []argoCDOpt{func(a *argoproj.ArgoCD) { a.Spec.HA.RedisProxyImage = "testing/redis-ha-haproxy" a.Spec.HA.RedisProxyVersion = "latest-ha" }}, @@ -207,7 +206,7 @@ var argoServerURITests = []struct { { name: "test with external host name", routeEnabled: false, - opts: []argoCDOpt{func(a *argoprojv1alpha1.ArgoCD) { + opts: []argoCDOpt{func(a *argoproj.ArgoCD) { a.Spec.Server.Host = "test-host-name" }}, want: "https://test-host-name", @@ -587,7 +586,7 @@ func TestSetManagedNamespaces(t *testing.T) { func TestSetManagedSourceNamespaces(t *testing.T) { a := makeTestArgoCD() - a.Spec = v1alpha1.ArgoCDSpec{ + a.Spec = argoproj.ArgoCDSpec{ SourceNamespaces: []string{ "test-namespace-1", }, @@ -642,10 +641,10 @@ func generateEncodedPEM(t *testing.T, host string) []byte { // TestReconcileArgoCD_reconcileDexOAuthClientSecret This test make sures that if dex is enabled a service account is created with token stored in a secret which is used for oauth func TestReconcileArgoCD_reconcileDexOAuthClientSecret(t *testing.T) { logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(ac *argoprojv1alpha1.ArgoCD) { - ac.Spec.SSO = &v1alpha1.ArgoCDSSOSpec{ - Provider: v1alpha1.SSOProviderTypeDex, - Dex: &v1alpha1.ArgoCDDexSpec{ + a := makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ OpenShiftOAuth: true, }, } diff --git a/controllers/argocdexport/export.go b/controllers/argocdexport/export.go index 9019ffe08..7aad286cb 100644 --- a/controllers/argocdexport/export.go +++ b/controllers/argocdexport/export.go @@ -20,8 +20,8 @@ import ( "github.com/sethvargo/go-password/password" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) @@ -38,7 +38,7 @@ func generateBackupKey() ([]byte, error) { } // reconcileExport will ensure that the resources for the export process are present for the ArgoCDExport. -func (r *ReconcileArgoCDExport) reconcileExport(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileExport(cr *argoprojv1alpha1.ArgoCDExport) error { log.Info("reconciling export secret") if err := r.reconcileExportSecret(cr); err != nil { return err @@ -60,10 +60,10 @@ func (r *ReconcileArgoCDExport) reconcileExport(cr *argoprojv1a1.ArgoCDExport) e } // reconcileExportSecret will ensure that the Secret used for the export process is present. -func (r *ReconcileArgoCDExport) reconcileExportSecret(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileExportSecret(cr *argoprojv1alpha1.ArgoCDExport) error { name := argoutil.FetchStorageSecretName(cr) // Dummy CR to retrieve secret - a := &argoprojv1a1.ArgoCD{} + a := &argoproj.ArgoCD{} a.ObjectMeta = cr.ObjectMeta secret := argoutil.NewSecretWithName(a, name) if argoutil.IsObjectFound(r.Client, cr.Namespace, name, secret) { diff --git a/controllers/argocdexport/job.go b/controllers/argocdexport/job.go index aeda5d910..577702b21 100644 --- a/controllers/argocdexport/job.go +++ b/controllers/argocdexport/job.go @@ -26,14 +26,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // getArgoExportCommand will return the command for the ArgoCD export process. -func getArgoExportCommand(cr *argoprojv1a1.ArgoCDExport) []string { +func getArgoExportCommand(cr *argoproj.ArgoCDExport) []string { cmd := make([]string, 0) cmd = append(cmd, "uid_entrypoint.sh") cmd = append(cmd, "argocd-operator-util") @@ -42,7 +42,7 @@ func getArgoExportCommand(cr *argoprojv1a1.ArgoCDExport) []string { return cmd } -func getArgoExportContainerEnv(cr *argoprojv1a1.ArgoCDExport) []corev1.EnvVar { +func getArgoExportContainerEnv(cr *argoproj.ArgoCDExport) []corev1.EnvVar { env := make([]corev1.EnvVar, 0) switch cr.Spec.Storage.Backend { @@ -76,7 +76,7 @@ func getArgoExportContainerEnv(cr *argoprojv1a1.ArgoCDExport) []corev1.EnvVar { } // getArgoExportContainerImage will return the container image for ArgoCD. -func getArgoExportContainerImage(cr *argoprojv1a1.ArgoCDExport) string { +func getArgoExportContainerImage(cr *argoproj.ArgoCDExport) string { img := cr.Spec.Image if len(img) <= 0 { img = common.ArgoCDDefaultExportJobImage @@ -108,7 +108,7 @@ func getArgoExportVolumeMounts() []corev1.VolumeMount { } // getArgoSecretVolume will return the Secret Volume for the export process. -func getArgoSecretVolume(name string, cr *argoprojv1a1.ArgoCDExport) corev1.Volume { +func getArgoSecretVolume(name string, cr *argoproj.ArgoCDExport) corev1.Volume { volume := corev1.Volume{ Name: name, } @@ -123,7 +123,7 @@ func getArgoSecretVolume(name string, cr *argoprojv1a1.ArgoCDExport) corev1.Volu } // getArgoStorageVolume will return the storage Volume for the export process. -func getArgoStorageVolume(name string, cr *argoprojv1a1.ArgoCDExport) corev1.Volume { +func getArgoStorageVolume(name string, cr *argoproj.ArgoCDExport) corev1.Volume { volume := corev1.Volume{ Name: name, } @@ -144,7 +144,7 @@ func getArgoStorageVolume(name string, cr *argoprojv1a1.ArgoCDExport) corev1.Vol } // newJob returns a new Job instance for the given ArgoCDExport. -func newJob(cr *argoprojv1a1.ArgoCDExport) *batchv1.Job { +func newJob(cr *argoproj.ArgoCDExport) *batchv1.Job { return &batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -155,7 +155,7 @@ func newJob(cr *argoprojv1a1.ArgoCDExport) *batchv1.Job { } // newCronJob returns a new CronJob instance for the given ArgoCDExport. -func newCronJob(cr *argoprojv1a1.ArgoCDExport) *batchv1.CronJob { +func newCronJob(cr *argoproj.ArgoCDExport) *batchv1.CronJob { return &batchv1.CronJob{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -165,7 +165,7 @@ func newCronJob(cr *argoprojv1a1.ArgoCDExport) *batchv1.CronJob { } } -func newExportPodSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string, client client.Client) corev1.PodSpec { +func newExportPodSpec(cr *argoproj.ArgoCDExport, argocdName string, client client.Client) corev1.PodSpec { pod := corev1.PodSpec{} boolPtr := func(value bool) *bool { @@ -210,7 +210,7 @@ func newExportPodSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string, client c return pod } -func newPodTemplateSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string, client client.Client) corev1.PodTemplateSpec { +func newPodTemplateSpec(cr *argoproj.ArgoCDExport, argocdName string, client client.Client) corev1.PodTemplateSpec { return corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Name: cr.Name, @@ -222,7 +222,7 @@ func newPodTemplateSpec(cr *argoprojv1a1.ArgoCDExport, argocdName string, client } // reconcileCronJob will ensure that the CronJob for the ArgoCDExport is present. -func (r *ReconcileArgoCDExport) reconcileCronJob(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileCronJob(cr *argoproj.ArgoCDExport) error { if cr.Spec.Storage == nil { return nil // Do nothing if storage options not set } @@ -257,7 +257,7 @@ func (r *ReconcileArgoCDExport) reconcileCronJob(cr *argoprojv1a1.ArgoCDExport) } // reconcileJob will ensure that the Job for the ArgoCDExport is present. -func (r *ReconcileArgoCDExport) reconcileJob(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileJob(cr *argoproj.ArgoCDExport) error { if cr.Spec.Storage == nil { return nil // Do nothing if storage options not set } @@ -288,7 +288,7 @@ func (r *ReconcileArgoCDExport) reconcileJob(cr *argoprojv1a1.ArgoCDExport) erro } func (r *ReconcileArgoCDExport) argocdName(namespace string) (string, error) { - argocds := &argoprojv1a1.ArgoCDList{} + argocds := &argoproj.ArgoCDList{} if err := r.Client.List(context.TODO(), argocds, &client.ListOptions{Namespace: namespace}); err != nil { return "", err } diff --git a/controllers/argocdexport/local.go b/controllers/argocdexport/local.go index 35c91ffd6..b3eaf22a8 100644 --- a/controllers/argocdexport/local.go +++ b/controllers/argocdexport/local.go @@ -22,13 +22,13 @@ import ( corev1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) // reconcileLocalStorage will ensure the PersistentVolumeClaim is present for the ArgoCDExport. -func (r *ReconcileArgoCDExport) reconcileLocalStorage(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileLocalStorage(cr *argoproj.ArgoCDExport) error { if cr.Spec.Storage == nil || strings.ToLower(cr.Spec.Storage.Backend) != common.ArgoCDExportStorageBackendLocal { return nil // Do nothing if storage or local options not set } @@ -41,7 +41,7 @@ func (r *ReconcileArgoCDExport) reconcileLocalStorage(cr *argoprojv1a1.ArgoCDExp } // reconcilePVC will ensure that the PVC for the ArgoCDExport is present. -func (r *ReconcileArgoCDExport) reconcilePVC(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcilePVC(cr *argoproj.ArgoCDExport) error { if cr.Status.Phase == common.ArgoCDStatusCompleted { return nil // Nothing to see here, move along... } diff --git a/controllers/argocdexport/reconcile.go b/controllers/argocdexport/reconcile.go index 2cf8adb4c..934a286ce 100644 --- a/controllers/argocdexport/reconcile.go +++ b/controllers/argocdexport/reconcile.go @@ -20,11 +20,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/builder" argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" ) // reconcileArgoCDExportResources will reconcile all ArgoCDExport resources for the give CR. -func (r *ReconcileArgoCDExport) reconcileArgoCDExportResources(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileArgoCDExportResources(cr *argoproj.ArgoCDExport) error { if err := r.validateExport(cr); err != nil { return err } diff --git a/controllers/argocdexport/storage.go b/controllers/argocdexport/storage.go index 75aca4fa4..169fb23dc 100644 --- a/controllers/argocdexport/storage.go +++ b/controllers/argocdexport/storage.go @@ -17,14 +17,14 @@ package argocdexport import ( "context" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1alpha1" "github.com/argoproj-labs/argocd-operator/common" ) // reconcileStorage will ensure that the storage options for the ArgoCDExport are present. -func (r *ReconcileArgoCDExport) reconcileStorage(cr *argoprojv1a1.ArgoCDExport) error { +func (r *ReconcileArgoCDExport) reconcileStorage(cr *argoproj.ArgoCDExport) error { if cr.Spec.Storage == nil { - cr.Spec.Storage = &argoprojv1a1.ArgoCDExportStorageSpec{ + cr.Spec.Storage = &argoproj.ArgoCDExportStorageSpec{ Backend: common.ArgoCDExportStorageBackendLocal, } return r.Client.Update(context.TODO(), cr) diff --git a/controllers/argoutil/resource.go b/controllers/argoutil/resource.go index 6d23ddca8..b5adada0f 100644 --- a/controllers/argoutil/resource.go +++ b/controllers/argoutil/resource.go @@ -25,7 +25,8 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) @@ -79,7 +80,7 @@ func FetchObject(client client.Client, namespace string, name string, obj client } // FetchStorageSecretName will return the name of the Secret to use for the export process. -func FetchStorageSecretName(export *argoprojv1a1.ArgoCDExport) string { +func FetchStorageSecretName(export *argoprojv1alpha1.ArgoCDExport) string { name := NameWithSuffix(export.ObjectMeta, "export") if export.Spec.Storage != nil && len(export.Spec.Storage.SecretName) > 0 { name = export.Spec.Storage.SecretName @@ -108,13 +109,13 @@ func newEvent(meta metav1.ObjectMeta) *corev1.Event { } // LabelsForCluster returns the labels for all cluster resources. -func LabelsForCluster(cr *argoprojv1a1.ArgoCD) map[string]string { +func LabelsForCluster(cr *argoproj.ArgoCD) map[string]string { labels := common.DefaultLabels(cr.Name) return labels } // annotationsForCluster returns the annotations for all cluster resources. -func AnnotationsForCluster(cr *argoprojv1a1.ArgoCD) map[string]string { +func AnnotationsForCluster(cr *argoproj.ArgoCD) map[string]string { annotations := common.DefaultAnnotations(cr.Name, cr.Namespace) for key, val := range cr.ObjectMeta.Annotations { annotations[key] = val diff --git a/controllers/argoutil/resource_test.go b/controllers/argoutil/resource_test.go index 04b8c9f3f..4ab3f01f1 100644 --- a/controllers/argoutil/resource_test.go +++ b/controllers/argoutil/resource_test.go @@ -20,13 +20,13 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) func TestDefaultAnnotations(t *testing.T) { type args struct { - cr *argoprojv1a1.ArgoCD + cr *argoproj.ArgoCD } tests := []struct { name string @@ -36,7 +36,7 @@ func TestDefaultAnnotations(t *testing.T) { { name: "simple annotations", args: args{ - &argoprojv1a1.ArgoCD{ + &argoproj.ArgoCD{ ObjectMeta: v1.ObjectMeta{ Name: "foo", Namespace: "bar", diff --git a/controllers/argoutil/secret.go b/controllers/argoutil/secret.go index f3709f855..7ed01ee91 100644 --- a/controllers/argoutil/secret.go +++ b/controllers/argoutil/secret.go @@ -21,28 +21,28 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - argoprojv1a1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" ) // FetchSecret will retrieve the object with the given Name using the provided client. // The result will be returned. func FetchSecret(client client.Client, meta metav1.ObjectMeta, name string) (*corev1.Secret, error) { - a := &argoprojv1a1.ArgoCD{} + a := &argoproj.ArgoCD{} a.ObjectMeta = meta secret := NewSecretWithName(a, name) return secret, FetchObject(client, meta.Namespace, name, secret) } // NewTLSSecret returns a new TLS Secret based on the given metadata with the provided suffix on the Name. -func NewTLSSecret(cr *argoprojv1a1.ArgoCD, suffix string) *corev1.Secret { +func NewTLSSecret(cr *argoproj.ArgoCD, suffix string) *corev1.Secret { secret := NewSecretWithSuffix(cr, suffix) secret.Type = corev1.SecretTypeTLS return secret } // NewSecret returns a new Secret based on the given metadata. -func NewSecret(cr *argoprojv1a1.ArgoCD) *corev1.Secret { +func NewSecret(cr *argoproj.ArgoCD) *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Labels: LabelsForCluster(cr), @@ -52,7 +52,7 @@ func NewSecret(cr *argoprojv1a1.ArgoCD) *corev1.Secret { } // NewSecretWithName returns a new Secret based on the given metadata with the provided Name. -func NewSecretWithName(cr *argoprojv1a1.ArgoCD, name string) *corev1.Secret { +func NewSecretWithName(cr *argoproj.ArgoCD, name string) *corev1.Secret { secret := NewSecret(cr) secret.ObjectMeta.Name = name @@ -63,6 +63,6 @@ func NewSecretWithName(cr *argoprojv1a1.ArgoCD, name string) *corev1.Secret { } // NewSecretWithSuffix returns a new Secret based on the given metadata with the provided suffix on the Name. -func NewSecretWithSuffix(cr *argoprojv1a1.ArgoCD, suffix string) *corev1.Secret { +func NewSecretWithSuffix(cr *argoproj.ArgoCD, suffix string) *corev1.Secret { return NewSecretWithName(cr, fmt.Sprintf("%s-%s", cr.Name, suffix)) } diff --git a/controllers/suite_testx.go b/controllers/suite_testx.go index d077043a8..b01089301 100644 --- a/controllers/suite_testx.go +++ b/controllers/suite_testx.go @@ -29,7 +29,8 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - argoprojiov1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + v1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + v1beta1 "github.com/argoproj-labs/argocd-operator/api/v1beta1" //+kubebuilder:scaffold:imports ) @@ -61,10 +62,10 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = argoprojiov1alpha1.AddToScheme(scheme.Scheme) + err = v1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = argoprojiov1alpha1.AddToScheme(scheme.Scheme) + err = v1beta1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:scheme From 380207e27e30efe8d2c353fe6c73a718daea531d Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:50:04 +0530 Subject: [PATCH 12/94] refactor: Remove deprecated .spec.resourceCustomizations (#973) * Remove .spec.resourceCustomizations code Signed-off-by: Siddhesh Ghadi * Update docs Signed-off-by: Siddhesh Ghadi * Update docs Signed-off-by: Siddhesh Ghadi * Address review comments Signed-off-by: Siddhesh Ghadi * Fix typo Signed-off-by: Siddhesh Ghadi --------- Signed-off-by: Siddhesh Ghadi --- api/v1alpha1/argocd_conversion.go | 2 - api/v1alpha1/argocd_types.go | 1 + api/v1beta1/argocd_types.go | 4 -- ...argocd-operator.clusterserviceversion.yaml | 15 ++--- bundle/manifests/argoproj.io_argocds.yaml | 15 ++--- common/defaults.go | 3 - common/keys.go | 3 - config/crd/bases/argoproj.io_argocds.yaml | 15 ++--- ...argocd-operator.clusterserviceversion.yaml | 15 ++--- controllers/argocd/configmap.go | 30 ---------- controllers/argocd/configmap_test.go | 59 ------------------- controllers/argocd/util.go | 7 +-- ...operator.v0.8.0.clusterserviceversion.yaml | 15 ++--- .../0.8.0/argoproj.io_argocds.yaml | 15 ++--- docs/reference/argocd.md | 48 ++------------- 15 files changed, 37 insertions(+), 210 deletions(-) diff --git a/api/v1alpha1/argocd_conversion.go b/api/v1alpha1/argocd_conversion.go index 104b3f8b4..64270ff43 100644 --- a/api/v1alpha1/argocd_conversion.go +++ b/api/v1alpha1/argocd_conversion.go @@ -79,7 +79,6 @@ func (src *ArgoCD) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.Redis = v1beta1.ArgoCDRedisSpec(src.Spec.Redis) dst.Spec.Repo = v1beta1.ArgoCDRepoSpec(src.Spec.Repo) dst.Spec.RepositoryCredentials = src.Spec.RepositoryCredentials - dst.Spec.ResourceCustomizations = src.Spec.ResourceCustomizations dst.Spec.ResourceHealthChecks = ConvertAlphaToBetaResourceHealthChecks(src.Spec.ResourceHealthChecks) dst.Spec.ResourceIgnoreDifferences = ConvertAlphaToBetaResourceIgnoreDifferences(src.Spec.ResourceIgnoreDifferences) dst.Spec.ResourceActions = ConvertAlphaToBetaResourceActions(src.Spec.ResourceActions) @@ -147,7 +146,6 @@ func (dst *ArgoCD) ConvertFrom(srcRaw conversion.Hub) error { dst.Spec.Redis = ArgoCDRedisSpec(src.Spec.Redis) dst.Spec.Repo = ArgoCDRepoSpec(src.Spec.Repo) dst.Spec.RepositoryCredentials = src.Spec.RepositoryCredentials - dst.Spec.ResourceCustomizations = src.Spec.ResourceCustomizations dst.Spec.ResourceHealthChecks = ConvertBetaToAlphaResourceHealthChecks(src.Spec.ResourceHealthChecks) dst.Spec.ResourceIgnoreDifferences = ConvertBetaToAlphaResourceIgnoreDifferences(src.Spec.ResourceIgnoreDifferences) dst.Spec.ResourceActions = ConvertBetaToAlphaResourceActions(src.Spec.ResourceActions) diff --git a/api/v1alpha1/argocd_types.go b/api/v1alpha1/argocd_types.go index 730290784..dfab608b5 100644 --- a/api/v1alpha1/argocd_types.go +++ b/api/v1alpha1/argocd_types.go @@ -761,6 +761,7 @@ type ArgoCDSpec struct { // RepositoryCredentials are the Git pull credentials to configure Argo CD with upon creation of the cluster. RepositoryCredentials string `json:"repositoryCredentials,omitempty"` + // Deprecated field. Support dropped in v1beta1 version. // ResourceCustomizations customizes resource behavior. Keys are in the form: group/Kind. Please note that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions. //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} ResourceCustomizations string `json:"resourceCustomizations,omitempty"` diff --git a/api/v1beta1/argocd_types.go b/api/v1beta1/argocd_types.go index 560ceca32..49af9f7cc 100644 --- a/api/v1beta1/argocd_types.go +++ b/api/v1beta1/argocd_types.go @@ -748,10 +748,6 @@ type ArgoCDSpec struct { // RepositoryCredentials are the Git pull credentials to configure Argo CD with upon creation of the cluster. RepositoryCredentials string `json:"repositoryCredentials,omitempty"` - // ResourceCustomizations customizes resource behavior. Keys are in the form: group/Kind. Please note that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions. - //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} - ResourceCustomizations string `json:"resourceCustomizations,omitempty"` - // ResourceHealthChecks customizes resource health check behavior. //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resource Health Check Customizations'",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:text","urn:alm:descriptor:com.tectonic.ui:advanced"} ResourceHealthChecks []ResourceHealthCheck `json:"resourceHealthChecks,omitempty"` diff --git a/bundle/manifests/argocd-operator.clusterserviceversion.yaml b/bundle/manifests/argocd-operator.clusterserviceversion.yaml index a34457ca3..5301692cb 100644 --- a/bundle/manifests/argocd-operator.clusterserviceversion.yaml +++ b/bundle/manifests/argocd-operator.clusterserviceversion.yaml @@ -685,9 +685,10 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'ResourceCustomizations customizes resource behavior. Keys are - in the form: group/Kind. Please note that this is being deprecated in favor - of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + - description: 'Deprecated field. Support dropped in v1beta1 version. ResourceCustomizations + customizes resource behavior. Keys are in the form: group/Kind. Please note + that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' displayName: Resource Customizations' path: resourceCustomizations x-descriptors: @@ -1262,14 +1263,6 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'ResourceCustomizations customizes resource behavior. Keys are - in the form: group/Kind. Please note that this is being deprecated in favor - of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' - displayName: Resource Customizations' - path: resourceCustomizations - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - urn:alm:descriptor:com.tectonic.ui:advanced - description: ResourceExclusions is used to completely ignore entire classes of resource group/kinds. displayName: Resource Exclusions' diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index eb6530c06..8d57db619 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -5669,10 +5669,11 @@ spec: type: object type: array resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' + description: 'Deprecated field. Support dropped in v1beta1 version. + ResourceCustomizations customizes resource behavior. Keys are in + the form: group/Kind. Please note that this is being deprecated + in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and + ResourceActions.' type: string resourceExclusions: description: ResourceExclusions is used to completely ignore entire @@ -12059,12 +12060,6 @@ spec: type: string type: object type: array - resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' - type: string resourceExclusions: description: ResourceExclusions is used to completely ignore entire classes of resource group/kinds. diff --git a/common/defaults.go b/common/defaults.go index 118b95e32..1690366a9 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -246,9 +246,6 @@ const ( // ArgoCDDefaultRepositoryCredentials is the default repository credentials ArgoCDDefaultRepositoryCredentials = "" - // ArgoCDDefaultResourceCustomizations is the default resource customizations. - ArgoCDDefaultResourceCustomizations = "" - // ArgoCDDefaultResourceExclusions is the default resource exclusions. ArgoCDDefaultResourceExclusions = "" diff --git a/common/keys.go b/common/keys.go index 65f2c1bb1..01db690f7 100644 --- a/common/keys.go +++ b/common/keys.go @@ -121,9 +121,6 @@ const ( // ArgoCDKeyRelease is the prometheus release key for labels. ArgoCDKeyRelease = "release" - // ArgoCDKeyResourceCustomizations is the configuration key for resource customizations. - ArgoCDKeyResourceCustomizations = "resource.customizations" - // ArgoCDKeyResourceExclusions is the configuration key for resource exclusions. ArgoCDKeyResourceExclusions = "resource.exclusions" diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 8a2a79f9a..772cf9477 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -5660,10 +5660,11 @@ spec: type: object type: array resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' + description: 'Deprecated field. Support dropped in v1beta1 version. + ResourceCustomizations customizes resource behavior. Keys are in + the form: group/Kind. Please note that this is being deprecated + in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and + ResourceActions.' type: string resourceExclusions: description: ResourceExclusions is used to completely ignore entire @@ -12050,12 +12051,6 @@ spec: type: string type: object type: array - resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' - type: string resourceExclusions: description: ResourceExclusions is used to completely ignore entire classes of resource group/kinds. diff --git a/config/manifests/bases/argocd-operator.clusterserviceversion.yaml b/config/manifests/bases/argocd-operator.clusterserviceversion.yaml index 03573a220..93894fa0e 100644 --- a/config/manifests/bases/argocd-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/argocd-operator.clusterserviceversion.yaml @@ -439,14 +439,6 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'ResourceCustomizations customizes resource behavior. Keys are - in the form: group/Kind. Please note that this is being deprecated in favor - of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' - displayName: Resource Customizations' - path: resourceCustomizations - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - urn:alm:descriptor:com.tectonic.ui:advanced - description: ResourceExclusions is used to completely ignore entire classes of resource group/kinds. displayName: Resource Exclusions' @@ -1048,9 +1040,10 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'ResourceCustomizations customizes resource behavior. Keys are - in the form: group/Kind. Please note that this is being deprecated in favor - of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + - description: 'Deprecated field. Support dropped in v1beta1 version. ResourceCustomizations + customizes resource behavior. Keys are in the form: group/Kind. Please note + that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' displayName: Resource Customizations' path: resourceCustomizations x-descriptors: diff --git a/controllers/argocd/configmap.go b/controllers/argocd/configmap.go index e8bf21ea7..5d64fab95 100644 --- a/controllers/argocd/configmap.go +++ b/controllers/argocd/configmap.go @@ -144,16 +144,6 @@ func getRBACScopes(cr *argoproj.ArgoCD) string { return scopes } -// getResourceCustomizations loads Resource Customizations from argocd-cm ConfigMap -func getResourceCustomizations(cr *argoproj.ArgoCD) string { - rc := common.ArgoCDDefaultResourceCustomizations - if cr.Spec.ResourceCustomizations != "" { - rc = cr.Spec.ResourceCustomizations - } - - return rc -} - // getResourceHealthChecks loads health customizations to `resource.customizations.health` from argocd-cm ConfigMap func getResourceHealthChecks(cr *argoproj.ArgoCD) map[string]string { healthCheck := make(map[string]string) @@ -408,26 +398,6 @@ func (r *ReconcileArgoCD) reconcileArgoConfigMap(cr *argoproj.ArgoCD) error { } } - // old format of ResourceCustomizations - if c := getResourceCustomizations(cr); c != "" { - - // Emit event providing users with deprecation notice for ResourceCustomization if not emitted already - if currentInstanceEventEmissionStatus, ok := DeprecationEventEmissionTracker[cr.Namespace]; !ok || !currentInstanceEventEmissionStatus.ResourceCustomizationsDeprecationWarningEmitted { - err := argoutil.CreateEvent(r.Client, "Warning", "Deprecated", "ResourceCustomizations is deprecated, and support will be removed in Argo CD Operator v0.8.0/OpenShift GitOps v1.10.0. Please use the new formats `ResourceHealthChecks`, `ResourceIgnoreDifferences`, and `ResourceActions`.", "DeprecationNotice", cr.ObjectMeta, cr.TypeMeta) - if err != nil { - return err - } - - if !ok { - currentInstanceEventEmissionStatus = DeprecationEventEmissionStatus{ResourceCustomizationsDeprecationWarningEmitted: true} - } else { - currentInstanceEventEmissionStatus.ResourceCustomizationsDeprecationWarningEmitted = true - } - DeprecationEventEmissionTracker[cr.Namespace] = currentInstanceEventEmissionStatus - } - cm.Data[common.ArgoCDKeyResourceCustomizations] = c - } - cm.Data[common.ArgoCDKeyResourceExclusions] = getResourceExclusions(cr) cm.Data[common.ArgoCDKeyResourceInclusions] = getResourceInclusions(cr) cm.Data[common.ArgoCDKeyResourceTrackingMethod] = getResourceTrackingMethod(cr) diff --git a/controllers/argocd/configmap_test.go b/controllers/argocd/configmap_test.go index bf2ed30f8..d00fc3ec3 100644 --- a/controllers/argocd/configmap_test.go +++ b/controllers/argocd/configmap_test.go @@ -679,29 +679,6 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceInclusions(t *testin } -func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceCustomizations(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - customizations := "testing: testing" - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.ResourceCustomizations = customizations - }) - r := makeTestReconciler(t, a) - - err := r.reconcileArgoConfigMap(a) - assert.NoError(t, err) - - cm := &corev1.ConfigMap{} - err = r.Client.Get(context.TODO(), types.NamespacedName{ - Name: common.ArgoCDConfigMapName, - Namespace: testNamespace, - }, cm) - assert.NoError(t, err) - - if c := cm.Data["resource.customizations"]; c != customizations { - t.Fatalf("reconcileArgoConfigMap failed got %q, want %q", c, customizations) - } -} - func TestReconcileArgoCD_reconcileArgoConfigMap_withNewResourceCustomizations(t *testing.T) { logf.SetLogger(ZapLogger(true)) @@ -792,42 +769,6 @@ managedfieldsmanagers: } } -func TestReconcile_emitEventOnDeprecatedResourceCustomizations(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - - DeprecationEventEmissionTracker = make(map[string]DeprecationEventEmissionStatus) - - resourceCustomizationsEvent := &corev1.Event{ - Reason: "DeprecationNotice", - Message: "ResourceCustomizations is deprecated, please use the new formats `ResourceHealthChecks`, `ResourceIgnoreDifferences`, and `ResourceActions` instead.", - Action: "Deprecated", - } - - tests := []struct { - name string - argoCD *argoproj.ArgoCD - wantEvents []*corev1.Event - }{ - { - name: "ResourceCustomizations used", - argoCD: makeTestArgoCD(func(ac *argoproj.ArgoCD) { - ac.Spec.ResourceCustomizations = "testing: testing" - }), - wantEvents: []*corev1.Event{resourceCustomizationsEvent}, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - r := makeFakeReconciler(t, test.argoCD) - err := r.reconcileArgoConfigMap(test.argoCD) - assert.NoError(t, err) - gotEventList := &corev1.EventList{} - err = r.Client.List(context.TODO(), gotEventList) - assert.NoError(t, err) - assert.Equal(t, len(test.wantEvents), len(gotEventList.Items)) - }) - } -} func TestReconcileArgoCD_reconcileArgoConfigMap_withExtraConfig(t *testing.T) { a := makeTestArgoCD() r := makeTestReconciler(t, a) diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index 6cb1dad4d..687189b6c 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -1158,10 +1158,9 @@ func containsString(arr []string, s string) bool { // DeprecationEventEmissionStatus is meant to track which deprecation events have been emitted already. This is temporary and can be removed in v0.0.6 once we have provided enough // deprecation notice type DeprecationEventEmissionStatus struct { - SSOSpecDeprecationWarningEmitted bool - DexSpecDeprecationWarningEmitted bool - DisableDexDeprecationWarningEmitted bool - ResourceCustomizationsDeprecationWarningEmitted bool + SSOSpecDeprecationWarningEmitted bool + DexSpecDeprecationWarningEmitted bool + DisableDexDeprecationWarningEmitted bool } // DeprecationEventEmissionTracker map stores the namespace containing ArgoCD instance as key and DeprecationEventEmissionStatus as value, diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml index a34457ca3..5301692cb 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argocd-operator.v0.8.0.clusterserviceversion.yaml @@ -685,9 +685,10 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'ResourceCustomizations customizes resource behavior. Keys are - in the form: group/Kind. Please note that this is being deprecated in favor - of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' + - description: 'Deprecated field. Support dropped in v1beta1 version. ResourceCustomizations + customizes resource behavior. Keys are in the form: group/Kind. Please note + that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' displayName: Resource Customizations' path: resourceCustomizations x-descriptors: @@ -1262,14 +1263,6 @@ spec: x-descriptors: - urn:alm:descriptor:com.tectonic.ui:text - urn:alm:descriptor:com.tectonic.ui:advanced - - description: 'ResourceCustomizations customizes resource behavior. Keys are - in the form: group/Kind. Please note that this is being deprecated in favor - of ResourceHealthChecks, ResourceIgnoreDifferences, and ResourceActions.' - displayName: Resource Customizations' - path: resourceCustomizations - x-descriptors: - - urn:alm:descriptor:com.tectonic.ui:text - - urn:alm:descriptor:com.tectonic.ui:advanced - description: ResourceExclusions is used to completely ignore entire classes of resource group/kinds. displayName: Resource Exclusions' diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index eb6530c06..8d57db619 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -5669,10 +5669,11 @@ spec: type: object type: array resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' + description: 'Deprecated field. Support dropped in v1beta1 version. + ResourceCustomizations customizes resource behavior. Keys are in + the form: group/Kind. Please note that this is being deprecated + in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and + ResourceActions.' type: string resourceExclusions: description: ResourceExclusions is used to completely ignore entire @@ -12059,12 +12060,6 @@ spec: type: string type: object type: array - resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' - type: string resourceExclusions: description: ResourceExclusions is used to completely ignore entire classes of resource group/kinds. diff --git a/docs/reference/argocd.md b/docs/reference/argocd.md index 7aa0e1db8..53112b10e 100644 --- a/docs/reference/argocd.md +++ b/docs/reference/argocd.md @@ -36,7 +36,9 @@ Name | Default | Description [**Prometheus**](#prometheus-options) | [Object] | Prometheus configuration options. [**RBAC**](#rbac-options) | [Object] | RBAC configuration options. [**Redis**](#redis-options) | [Object] | Redis configuration options. -[**ResourceCustomizations**](#resource-customizations) | [Empty] | Customize resource behavior. +[**ResourceHealthChecks**](#resource-customizations) | [Empty] | Customizes resource health check behavior. +[**ResourceIgnoreDifferences**](#resource-customizations) | [Empty] | Customizes resource ignore difference behavior. +[**ResourceActions**](#resource-customizations) | [Empty] | Customizes resource action behavior. [**ResourceExclusions**](#resource-exclusions) | [Empty] | The configuration to completely ignore entire classes of resource group/kinds. [**ResourceInclusions**](#resource-inclusions) | [Empty] | The configuration to configure which resource group/kinds are applied. [**ResourceTrackingMethod**](#resource-tracking-method) | `label` | The resource tracking method Argo CD should use. @@ -942,10 +944,10 @@ spec: ## Resource Customizations -There are two ways to customize resource behavior- the first way, only available with release v0.5.0+, is with subkeys (`resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions`), the second is without subkeys (`resourceCustomizations`). `resourceCustomizations` maps directly to the `resource.customizations` field in the `argocd-cm` ConfigMap, while each of the subkeys maps directly to their own field in the `argocd-cm`. `resourceHealthChecks` will map to `resource.customizations.health`, `resourceIgnoreDifferences` to `resource.customizations.ignoreDifferences`, and `resourceActions` to `resource.customizations.actions`. +Resource behavior can be customized using subkeys (`resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions`). Each of the subkeys maps directly to their own field in the `argocd-cm`. `resourceHealthChecks` will map to `resource.customizations.health`, `resourceIgnoreDifferences` to `resource.customizations.ignoreDifferences`, and `resourceActions` to `resource.customizations.actions`. -!!! warning - `resourceCustomizations` is being deprecated, and support will be removed in Argo CD Operator v0.8.0 so is encouraged to use `resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions` instead. It is the user's responsibility to not provide conflicting resources if they choose to use both methods of resource customizations. +!!! note + `.spec.resourceCustomizations` field is no longer in support from Argo CD Operator v0.8.0 onward. Consider using `resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions` instead. ### Resource Customizations (with subkeys) @@ -1145,44 +1147,6 @@ resource.customizations.ignoreDifferences.all: | - /spec/replicas ``` -### Resource Customizations Example - -!!! warning - `resourceCustomizations` is being deprecated, and support will be removed in Argo CD Operator v0.8.0. Please use the new formats `resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions`. - -The following example defines a custom PVC health check in the `argocd-cm` ConfigMap using the `ResourceCustomizations` property on the `ArgoCD` resource. - -``` yaml -apiVersion: argoproj.io/v1alpha1 -kind: ArgoCD -metadata: - name: example-argocd - labels: - example: resource-customizations -spec: - resourceCustomizations: | - PersistentVolumeClaim: - health.lua: | - hs = {} - if obj.status ~= nil then - if obj.status.phase ~= nil then - if obj.status.phase == "Pending" then - hs.status = "Healthy" - hs.message = obj.status.phase - return hs - end - if obj.status.phase == "Bound" then - hs.status = "Healthy" - hs.message = obj.status.phase - return hs - end - end - end - hs.status = "Progressing" - hs.message = "Waiting for certificate" - return hs -``` - ## Resource Exclusions Configuration to completely ignore entire classes of resource group/kinds (optional). From f2f9fb455a6870b6145cb973f577e70b15ca086a Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Wed, 30 Aug 2023 04:56:34 -0400 Subject: [PATCH 13/94] upgrade ArgoCD version to 2.8.2 and update the CRDs (#984) * upgrade ArgoCD version to 2.8.2 and update the CRDs Signed-off-by: ishitasequeira * Update argocd image Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira --- build/util/Dockerfile | 4 +- .../manifests/argoproj.io_applications.yaml | 151 +- .../argoproj.io_applicationsets.yaml | 5794 +++++++++++------ common/defaults.go | 2 +- .../crd/bases/argoproj.io_applications.yaml | 151 +- .../bases/argoproj.io_applicationsets.yaml | 5794 +++++++++++------ .../0.8.0/argoproj.io_applications.yaml | 151 +- .../0.8.0/argoproj.io_applicationsets.yaml | 5794 +++++++++++------ go.mod | 24 +- go.sum | 47 +- 10 files changed, 12150 insertions(+), 5762 deletions(-) diff --git a/build/util/Dockerfile b/build/util/Dockerfile index 76de99508..f4475c941 100644 --- a/build/util/Dockerfile +++ b/build/util/Dockerfile @@ -1,5 +1,5 @@ -# Argo CD v2.7.6 -FROM quay.io/argoproj/argocd@sha256:7daba5f38b23f4f091951b727db6f87dc04ad396fd21044401502438d633836e as argocd +# Argo CD v2.8.2 +FROM quay.io/argoproj/argocd@sha256:14e293cd7e35169c45ec51cccdabb80da72c434d7e16d60d3de2ce3a23f08c4b as argocd # Final Image FROM docker.io/library/ubuntu:22.04 diff --git a/bundle/manifests/argoproj.io_applications.yaml b/bundle/manifests/argoproj.io_applications.yaml index 5a6d15a02..79c4b81db 100644 --- a/bundle/manifests/argoproj.io_applications.yaml +++ b/bundle/manifests/argoproj.io_applications.yaml @@ -287,8 +287,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -576,8 +583,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -982,8 +996,15 @@ spec: type: array values: description: Values specifies Helm values to be passed to - helm template, typically defined as a block + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1262,8 +1283,15 @@ spec: type: array values: description: Values specifies Helm values to be passed to - helm template, typically defined as a block + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1511,6 +1539,10 @@ spec: - type type: object type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string health: description: Health contains information about the application's current health status @@ -1690,8 +1722,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1983,8 +2022,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -2421,8 +2468,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over + Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -2730,8 +2784,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined - as a block + as a block. ValuesObject takes precedence + over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3156,8 +3217,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3460,8 +3529,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over Values, + so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3731,6 +3807,42 @@ spec: and must be set to the Kubernetes control plane API type: string type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted + managers. Fields mutated by those managers will take + precedence over the desired state defined in the SCM + and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array source: description: Source is a reference to the application's source used for comparison @@ -3869,8 +3981,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -4173,8 +4293,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over Values, + so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") diff --git a/bundle/manifests/argoproj.io_applicationsets.yaml b/bundle/manifests/argoproj.io_applicationsets.yaml index 6e2a03d1b..0b351c7b8 100644 --- a/bundle/manifests/argoproj.io_applicationsets.yaml +++ b/bundle/manifests/argoproj.io_applicationsets.yaml @@ -30,6 +30,8 @@ spec: type: object spec: properties: + applyNestedSelectors: + type: boolean generators: items: properties: @@ -225,6 +227,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -402,6 +407,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -738,6 +746,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -915,6 +926,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1255,6 +1269,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1432,6 +1449,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1576,6 +1596,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - repoURL - revision @@ -1748,6 +1772,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1925,6 +1952,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2269,6 +2299,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2446,6 +2479,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2782,6 +2818,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2959,6 +2998,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3299,6 +3341,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3476,6 +3521,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3620,6 +3668,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - repoURL - revision @@ -3792,6 +3844,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3969,6 +4024,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4120,123 +4178,21 @@ spec: x-kubernetes-preserve-unknown-fields: true merge: x-kubernetes-preserve-unknown-fields: true - pullRequest: + plugin: properties: - bitbucketServer: - properties: - api: - type: string - basicAuth: - properties: - passwordRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - repo: - type: string - required: - - api - - project - - repo - type: object - filters: - items: - properties: - branchMatch: - type: string - type: object - type: array - gitea: - properties: - api: - type: string - insecure: - type: boolean - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - - repo - type: object - github: + configMapRef: properties: - api: - type: string - appSecretName: - type: string - labels: - items: - type: string - type: array - owner: - type: string - repo: + name: type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object required: - - owner - - repo + - name type: object - gitlab: + input: properties: - api: - type: string - labels: - items: - type: string - type: array - project: - type: string - pullRequestState: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true type: object - required: - - project type: object requeueAfterSeconds: format: int64 @@ -4401,6 +4357,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4578,6 +4537,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4722,12 +4684,30 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef type: object - scmProvider: + pullRequest: properties: - azureDevOps: + azuredevops: properties: - accessTokenRef: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: properties: key: type: string @@ -4737,46 +4717,58 @@ spec: - key - secretName type: object - allBranches: - type: boolean - api: - type: string - organization: - type: string - teamProject: - type: string required: - - accessTokenRef - organization - - teamProject + - project + - repo type: object bitbucket: properties: - allBranches: - type: boolean - appPasswordRef: + api: + type: string + basicAuth: properties: - key: - type: string - secretName: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: type: string required: - - key - - secretName + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef type: object owner: type: string - user: + repo: type: string required: - - appPasswordRef - owner - - user + - repo type: object bitbucketServer: properties: - allBranches: - type: boolean api: type: string basicAuth: @@ -4799,41 +4791,32 @@ spec: type: object project: type: string + repo: + type: string required: - api - project + - repo type: object - cloneProtocol: - type: string filters: items: properties: branchMatch: type: string - labelMatch: - type: string - pathsDoNotExist: - items: - type: string - type: array - pathsExist: - items: - type: string - type: array - repositoryMatch: + targetBranchMatch: type: string type: object type: array gitea: properties: - allBranches: - type: boolean api: type: string insecure: type: boolean owner: type: string + repo: + type: string tokenRef: properties: key: @@ -4847,16 +4830,21 @@ spec: required: - api - owner + - repo type: object github: properties: - allBranches: - type: boolean api: type: string appSecretName: type: string - organization: + labels: + items: + type: string + type: array + owner: + type: string + repo: type: string tokenRef: properties: @@ -4869,18 +4857,23 @@ spec: - secretName type: object required: - - organization + - owner + - repo type: object gitlab: properties: - allBranches: - type: boolean api: type: string - group: - type: string - includeSubgroups: + insecure: type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string tokenRef: properties: key: @@ -4892,7 +4885,7 @@ spec: - secretName type: object required: - - group + - project type: object requeueAfterSeconds: format: int64 @@ -5057,6 +5050,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -5234,6 +5230,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -5379,562 +5378,212 @@ spec: - spec type: object type: object - selector: + scmProvider: properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: object - type: array - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: + awsCodeCommit: properties: - group: + allBranches: + type: boolean + region: type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: + role: type: string - managedFieldsManagers: + tagFilters: items: - type: string + properties: + key: + type: string + value: + type: string + required: + - key + type: object type: array - name: + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: type: string - namespace: + organization: + type: string + teamProject: type: string required: - - kind + - accessTokenRef + - organization + - teamProject type: object - type: array - info: - items: + bitbucket: properties: - name: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: type: string - value: + user: type: string required: - - name - - value + - appPasswordRef + - owner + - user type: object - type: array - project: - type: string - revisionHistoryLimit: - format: int64 - type: integer - source: - properties: - chart: - type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: - properties: - fileParameters: - items: + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: properties: - name: + key: type: string - path: + secretName: type: string + required: + - key + - secretName type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string type: array - ignoreMissingValueFiles: - type: boolean - parameters: + pathsExist: items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object + type: string type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: + repositoryMatch: type: string type: object - kustomize: - properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: + secretName: type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object - sources: - items: + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: properties: - chart: + allBranches: + type: boolean + api: type: string - directory: + appSecretName: + type: string + organization: + type: string + tokenRef: properties: - exclude: + key: type: string - include: + secretName: type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean + required: + - key + - secretName type: object - helm: + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: + key: type: string - version: + secretName: type: string + required: + - key + - secretName type: object - kustomize: + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: properties: - commonAnnotations: + annotations: additionalProperties: type: string type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object - type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: - type: string - type: array - type: object - required: - - destination - - project - type: object - required: - - metadata - - spec - type: object - required: - - generators - type: object - merge: - properties: - generators: - items: - properties: - clusterDecisionResource: - properties: - configMapRef: - type: string - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - name: - type: string - requeueAfterSeconds: - format: int64 - type: integer - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: + finalizers: + items: type: string type: array labels: @@ -6085,6 +5734,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -6262,6 +5914,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -6410,560 +6065,568 @@ spec: additionalProperties: type: string type: object - required: - - configMapRef type: object - clusters: + selector: properties: - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: + matchExpressions: + items: + properties: + key: type: string - type: object - type: object - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: + operator: + type: string + values: + items: type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: - type: string - revisionHistoryLimit: - format: int64 - type: integer - source: - properties: - chart: - type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: + code: type: boolean - valueFiles: - items: - type: string - type: array - values: + name: type: string - version: + value: type: string + required: + - name + - value type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: + name: type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string path: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - repoURL: + value: type: string - targetRevision: + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object - sources: - items: - properties: - chart: + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: type: string - directory: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - exclude: + code: + type: boolean + name: type: string - include: + value: type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean + required: + - name + - value type: object - helm: - properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: - type: string - type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object - path: + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + path: type: string - repoURL: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - targetRevision: + value: type: string - required: - - repoURL type: object type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: - type: string - type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: type: object - required: - - destination - - project + x-kubernetes-preserve-unknown-fields: true + version: + type: string type: object - required: - - metadata - - spec - type: object - values: - additionalProperties: - type: string - type: object - type: object - git: - properties: - directories: - items: - properties: - exclude: - type: boolean - path: - type: string - required: - - path - type: object - type: array - files: - items: - properties: - path: - type: string - required: - - path - type: object - type: array - pathParamPrefix: - type: string - repoURL: - type: string - requeueAfterSeconds: - format: int64 - type: integer - revision: - type: string - template: - properties: - metadata: + kustomize: properties: - annotations: + commonAnnotations: additionalProperties: type: string type: object - finalizers: + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: items: type: string type: array @@ -7115,6 +6778,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7292,6 +6958,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7436,18 +7105,38 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - - repoURL - - revision + - configMapRef type: object - list: + clusters: properties: - elements: - items: - x-kubernetes-preserve-unknown-fields: true - type: array - elementsYaml: - type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object template: properties: metadata: @@ -7608,6 +7297,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7785,6 +7477,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7929,134 +7624,42 @@ spec: - metadata - spec type: object - required: - - elements + values: + additionalProperties: + type: string + type: object type: object - matrix: - x-kubernetes-preserve-unknown-fields: true - merge: - x-kubernetes-preserve-unknown-fields: true - pullRequest: + git: properties: - bitbucketServer: - properties: - api: - type: string - basicAuth: - properties: - passwordRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - repo: - type: string - required: - - api - - project - - repo - type: object - filters: + directories: items: properties: - branchMatch: + exclude: + type: boolean + path: type: string + required: + - path type: object type: array - gitea: - properties: - api: - type: string - insecure: - type: boolean - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - - repo - type: object - github: - properties: - api: - type: string - appSecretName: - type: string - labels: - items: - type: string - type: array - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - owner - - repo - type: object - gitlab: - properties: - api: - type: string - labels: - items: + files: + items: + properties: + path: type: string - type: array - project: - type: string - pullRequestState: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - project - type: object + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string requeueAfterSeconds: format: int64 type: integer + revision: + type: string template: properties: metadata: @@ -8217,6 +7820,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -8394,6 +8000,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -8538,253 +8147,94 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision type: object - scmProvider: + list: properties: - azureDevOps: - properties: - accessTokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - allBranches: - type: boolean - api: - type: string - organization: - type: string - teamProject: - type: string - required: - - accessTokenRef - - organization - - teamProject - type: object - bitbucket: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: properties: - allBranches: - type: boolean - appPasswordRef: + metadata: properties: - key: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: type: string - secretName: + namespace: type: string - required: - - key - - secretName type: object - owner: - type: string - user: - type: string - required: - - appPasswordRef - - owner - - user - type: object - bitbucketServer: - properties: - allBranches: - type: boolean - api: - type: string - basicAuth: + spec: properties: - passwordRef: + destination: properties: - key: + name: type: string - secretName: + namespace: + type: string + server: type: string - required: - - key - - secretName type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - required: - - api - - project - type: object - cloneProtocol: - type: string - filters: - items: - properties: - branchMatch: - type: string - labelMatch: - type: string - pathsDoNotExist: - items: - type: string - type: array - pathsExist: - items: - type: string - type: array - repositoryMatch: - type: string - type: object - type: array - gitea: - properties: - allBranches: - type: boolean - api: - type: string - insecure: - type: boolean - owner: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - type: object - github: - properties: - allBranches: - type: boolean - api: - type: string - appSecretName: - type: string - organization: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - organization - type: object - gitlab: - properties: - allBranches: - type: boolean - api: - type: string - group: - type: string - includeSubgroups: - type: boolean - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - group - type: object - requeueAfterSeconds: - format: int64 - type: integer - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: type: string revisionHistoryLimit: format: int64 @@ -8826,404 +8276,2814 @@ spec: type: boolean name: type: string - value: + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: + allowEmpty: type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: + prune: type: boolean - releaseName: - type: string - skipCrds: + selfHeal: type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: - type: string type: object - kustomize: + managedNamespaceMetadata: properties: - commonAnnotations: + annotations: additionalProperties: type: string type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: + labels: additionalProperties: type: string type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object - path: + type: array + libs: + items: type: string - plugin: + type: array + tlas: + items: properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array + code: + type: boolean name: type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array + value: + type: string + required: + - name + - value type: object - ref: + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: type: string - repoURL: + path: type: string - targetRevision: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object - sources: - items: - properties: - chart: + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: + code: type: boolean - valueFiles: - items: - type: string - type: array - values: + name: type: string - version: + value: type: string + required: + - name + - value type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string path: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - repoURL: + value: type: string - targetRevision: + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: type: string - type: array - type: object - required: - - destination - - project + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string required: - - metadata - - spec + - repoURL type: object - type: object - selector: - properties: - matchExpressions: - items: + type: array + syncPolicy: + properties: + automated: properties: - key: - type: string - operator: - type: string - values: - items: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: type: string - type: array - required: - - key - - operator + type: object + labels: + additionalProperties: + type: string + type: object type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: object - type: array - mergeKeys: - items: - type: string - type: array + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer template: properties: metadata: @@ -9384,6 +11244,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -9561,6 +11424,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -9705,12 +11571,89 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - - generators - - mergeKeys + - configMapRef type: object pullRequest: properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object bitbucketServer: properties: api: @@ -9747,6 +11690,8 @@ spec: properties: branchMatch: type: string + targetBranchMatch: + type: string type: object type: array gitea: @@ -9806,6 +11751,8 @@ spec: properties: api: type: string + insecure: + type: boolean labels: items: type: string @@ -9990,6 +11937,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10167,6 +12117,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10314,6 +12267,26 @@ spec: type: object scmProvider: properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object azureDevOps: properties: accessTokenRef: @@ -10470,6 +12443,8 @@ spec: type: string includeSubgroups: type: boolean + insecure: + type: boolean tokenRef: properties: key: @@ -10646,6 +12621,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10823,6 +12801,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10967,6 +12948,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object type: object selector: properties: @@ -10995,6 +12980,10 @@ spec: type: array goTemplate: type: boolean + goTemplateOptions: + items: + type: string + type: array preservedFields: properties: annotations: @@ -11035,6 +13024,13 @@ spec: type: object syncPolicy: properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string preserveResourcesOnDeletion: type: boolean type: object @@ -11198,6 +13194,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -11375,6 +13374,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object diff --git a/common/defaults.go b/common/defaults.go index 1690366a9..9bb236411 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -61,7 +61,7 @@ const ( ArgoCDDefaultArgoImage = "quay.io/argoproj/argocd" // ArgoCDDefaultArgoVersion is the Argo CD container image digest to use when version not specified. - ArgoCDDefaultArgoVersion = "sha256:7daba5f38b23f4f091951b727db6f87dc04ad396fd21044401502438d633836e" // v2.7.6 + ArgoCDDefaultArgoVersion = "sha256:14e293cd7e35169c45ec51cccdabb80da72c434d7e16d60d3de2ce3a23f08c4b" // v2.8.2 // ArgoCDDefaultBackupKeyLength is the length of the generated default backup key. ArgoCDDefaultBackupKeyLength = 32 diff --git a/config/crd/bases/argoproj.io_applications.yaml b/config/crd/bases/argoproj.io_applications.yaml index 6f5f5d079..fc6282dd3 100644 --- a/config/crd/bases/argoproj.io_applications.yaml +++ b/config/crd/bases/argoproj.io_applications.yaml @@ -286,8 +286,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -575,8 +582,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -981,8 +995,15 @@ spec: type: array values: description: Values specifies Helm values to be passed to - helm template, typically defined as a block + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1261,8 +1282,15 @@ spec: type: array values: description: Values specifies Helm values to be passed to - helm template, typically defined as a block + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1510,6 +1538,10 @@ spec: - type type: object type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string health: description: Health contains information about the application's current health status @@ -1689,8 +1721,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1982,8 +2021,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -2420,8 +2467,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over + Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -2729,8 +2783,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined - as a block + as a block. ValuesObject takes precedence + over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3155,8 +3216,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3459,8 +3528,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over Values, + so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3730,6 +3806,42 @@ spec: and must be set to the Kubernetes control plane API type: string type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted + managers. Fields mutated by those managers will take + precedence over the desired state defined in the SCM + and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array source: description: Source is a reference to the application's source used for comparison @@ -3868,8 +3980,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -4172,8 +4292,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over Values, + so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") diff --git a/config/crd/bases/argoproj.io_applicationsets.yaml b/config/crd/bases/argoproj.io_applicationsets.yaml index dc3ce3a06..72d23d94a 100644 --- a/config/crd/bases/argoproj.io_applicationsets.yaml +++ b/config/crd/bases/argoproj.io_applicationsets.yaml @@ -29,6 +29,8 @@ spec: type: object spec: properties: + applyNestedSelectors: + type: boolean generators: items: properties: @@ -224,6 +226,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -401,6 +406,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -737,6 +745,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -914,6 +925,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1254,6 +1268,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1431,6 +1448,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1575,6 +1595,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - repoURL - revision @@ -1747,6 +1771,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1924,6 +1951,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2268,6 +2298,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2445,6 +2478,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2781,6 +2817,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2958,6 +2997,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3298,6 +3340,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3475,6 +3520,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3619,6 +3667,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - repoURL - revision @@ -3791,6 +3843,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3968,6 +4023,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4119,123 +4177,21 @@ spec: x-kubernetes-preserve-unknown-fields: true merge: x-kubernetes-preserve-unknown-fields: true - pullRequest: + plugin: properties: - bitbucketServer: - properties: - api: - type: string - basicAuth: - properties: - passwordRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - repo: - type: string - required: - - api - - project - - repo - type: object - filters: - items: - properties: - branchMatch: - type: string - type: object - type: array - gitea: - properties: - api: - type: string - insecure: - type: boolean - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - - repo - type: object - github: + configMapRef: properties: - api: - type: string - appSecretName: - type: string - labels: - items: - type: string - type: array - owner: - type: string - repo: + name: type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object required: - - owner - - repo + - name type: object - gitlab: + input: properties: - api: - type: string - labels: - items: - type: string - type: array - project: - type: string - pullRequestState: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true type: object - required: - - project type: object requeueAfterSeconds: format: int64 @@ -4400,6 +4356,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4577,6 +4536,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4721,12 +4683,30 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef type: object - scmProvider: + pullRequest: properties: - azureDevOps: + azuredevops: properties: - accessTokenRef: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: properties: key: type: string @@ -4736,46 +4716,58 @@ spec: - key - secretName type: object - allBranches: - type: boolean - api: - type: string - organization: - type: string - teamProject: - type: string required: - - accessTokenRef - organization - - teamProject + - project + - repo type: object bitbucket: properties: - allBranches: - type: boolean - appPasswordRef: + api: + type: string + basicAuth: properties: - key: - type: string - secretName: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: type: string required: - - key - - secretName + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef type: object owner: type: string - user: + repo: type: string required: - - appPasswordRef - owner - - user + - repo type: object bitbucketServer: properties: - allBranches: - type: boolean api: type: string basicAuth: @@ -4798,41 +4790,32 @@ spec: type: object project: type: string + repo: + type: string required: - api - project + - repo type: object - cloneProtocol: - type: string filters: items: properties: branchMatch: type: string - labelMatch: - type: string - pathsDoNotExist: - items: - type: string - type: array - pathsExist: - items: - type: string - type: array - repositoryMatch: + targetBranchMatch: type: string type: object type: array gitea: properties: - allBranches: - type: boolean api: type: string insecure: type: boolean owner: type: string + repo: + type: string tokenRef: properties: key: @@ -4846,16 +4829,21 @@ spec: required: - api - owner + - repo type: object github: properties: - allBranches: - type: boolean api: type: string appSecretName: type: string - organization: + labels: + items: + type: string + type: array + owner: + type: string + repo: type: string tokenRef: properties: @@ -4868,18 +4856,23 @@ spec: - secretName type: object required: - - organization + - owner + - repo type: object gitlab: properties: - allBranches: - type: boolean api: type: string - group: - type: string - includeSubgroups: + insecure: type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string tokenRef: properties: key: @@ -4891,7 +4884,7 @@ spec: - secretName type: object required: - - group + - project type: object requeueAfterSeconds: format: int64 @@ -5056,6 +5049,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -5233,6 +5229,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -5378,562 +5377,212 @@ spec: - spec type: object type: object - selector: + scmProvider: properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: object - type: array - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: + awsCodeCommit: properties: - group: + allBranches: + type: boolean + region: type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: + role: type: string - managedFieldsManagers: + tagFilters: items: - type: string + properties: + key: + type: string + value: + type: string + required: + - key + type: object type: array - name: + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: type: string - namespace: + organization: + type: string + teamProject: type: string required: - - kind + - accessTokenRef + - organization + - teamProject type: object - type: array - info: - items: + bitbucket: properties: - name: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: type: string - value: + user: type: string required: - - name - - value + - appPasswordRef + - owner + - user type: object - type: array - project: - type: string - revisionHistoryLimit: - format: int64 - type: integer - source: - properties: - chart: - type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: - properties: - fileParameters: - items: + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: properties: - name: + key: type: string - path: + secretName: type: string + required: + - key + - secretName type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string type: array - ignoreMissingValueFiles: - type: boolean - parameters: + pathsExist: items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object + type: string type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: + repositoryMatch: type: string type: object - kustomize: - properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: + secretName: type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object - sources: - items: + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: properties: - chart: + allBranches: + type: boolean + api: type: string - directory: + appSecretName: + type: string + organization: + type: string + tokenRef: properties: - exclude: + key: type: string - include: + secretName: type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean + required: + - key + - secretName type: object - helm: + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: + key: type: string - version: + secretName: type: string + required: + - key + - secretName type: object - kustomize: + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: properties: - commonAnnotations: + annotations: additionalProperties: type: string type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object - type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: - type: string - type: array - type: object - required: - - destination - - project - type: object - required: - - metadata - - spec - type: object - required: - - generators - type: object - merge: - properties: - generators: - items: - properties: - clusterDecisionResource: - properties: - configMapRef: - type: string - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - name: - type: string - requeueAfterSeconds: - format: int64 - type: integer - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: + finalizers: + items: type: string type: array labels: @@ -6084,6 +5733,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -6261,6 +5913,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -6409,560 +6064,568 @@ spec: additionalProperties: type: string type: object - required: - - configMapRef type: object - clusters: + selector: properties: - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: + matchExpressions: + items: + properties: + key: type: string - type: object - type: object - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: + operator: + type: string + values: + items: type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: - type: string - revisionHistoryLimit: - format: int64 - type: integer - source: - properties: - chart: - type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: + code: type: boolean - valueFiles: - items: - type: string - type: array - values: + name: type: string - version: + value: type: string + required: + - name + - value type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: + name: type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string path: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - repoURL: + value: type: string - targetRevision: + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object - sources: - items: - properties: - chart: + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: type: string - directory: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - exclude: + code: + type: boolean + name: type: string - include: + value: type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean + required: + - name + - value type: object - helm: - properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: - type: string - type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object - path: + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + path: type: string - repoURL: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - targetRevision: + value: type: string - required: - - repoURL type: object type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: - type: string - type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: type: object - required: - - destination - - project + x-kubernetes-preserve-unknown-fields: true + version: + type: string type: object - required: - - metadata - - spec - type: object - values: - additionalProperties: - type: string - type: object - type: object - git: - properties: - directories: - items: - properties: - exclude: - type: boolean - path: - type: string - required: - - path - type: object - type: array - files: - items: - properties: - path: - type: string - required: - - path - type: object - type: array - pathParamPrefix: - type: string - repoURL: - type: string - requeueAfterSeconds: - format: int64 - type: integer - revision: - type: string - template: - properties: - metadata: + kustomize: properties: - annotations: + commonAnnotations: additionalProperties: type: string type: object - finalizers: + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: items: type: string type: array @@ -7114,6 +6777,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7291,6 +6957,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7435,18 +7104,38 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - - repoURL - - revision + - configMapRef type: object - list: + clusters: properties: - elements: - items: - x-kubernetes-preserve-unknown-fields: true - type: array - elementsYaml: - type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object template: properties: metadata: @@ -7607,6 +7296,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7784,6 +7476,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7928,134 +7623,42 @@ spec: - metadata - spec type: object - required: - - elements + values: + additionalProperties: + type: string + type: object type: object - matrix: - x-kubernetes-preserve-unknown-fields: true - merge: - x-kubernetes-preserve-unknown-fields: true - pullRequest: + git: properties: - bitbucketServer: - properties: - api: - type: string - basicAuth: - properties: - passwordRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - repo: - type: string - required: - - api - - project - - repo - type: object - filters: + directories: items: properties: - branchMatch: + exclude: + type: boolean + path: type: string + required: + - path type: object type: array - gitea: - properties: - api: - type: string - insecure: - type: boolean - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - - repo - type: object - github: - properties: - api: - type: string - appSecretName: - type: string - labels: - items: - type: string - type: array - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - owner - - repo - type: object - gitlab: - properties: - api: - type: string - labels: - items: + files: + items: + properties: + path: type: string - type: array - project: - type: string - pullRequestState: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - project - type: object + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string requeueAfterSeconds: format: int64 type: integer + revision: + type: string template: properties: metadata: @@ -8216,6 +7819,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -8393,6 +7999,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -8537,253 +8146,94 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision type: object - scmProvider: + list: properties: - azureDevOps: - properties: - accessTokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - allBranches: - type: boolean - api: - type: string - organization: - type: string - teamProject: - type: string - required: - - accessTokenRef - - organization - - teamProject - type: object - bitbucket: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: properties: - allBranches: - type: boolean - appPasswordRef: + metadata: properties: - key: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: type: string - secretName: + namespace: type: string - required: - - key - - secretName type: object - owner: - type: string - user: - type: string - required: - - appPasswordRef - - owner - - user - type: object - bitbucketServer: - properties: - allBranches: - type: boolean - api: - type: string - basicAuth: + spec: properties: - passwordRef: + destination: properties: - key: + name: type: string - secretName: + namespace: + type: string + server: type: string - required: - - key - - secretName type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - required: - - api - - project - type: object - cloneProtocol: - type: string - filters: - items: - properties: - branchMatch: - type: string - labelMatch: - type: string - pathsDoNotExist: - items: - type: string - type: array - pathsExist: - items: - type: string - type: array - repositoryMatch: - type: string - type: object - type: array - gitea: - properties: - allBranches: - type: boolean - api: - type: string - insecure: - type: boolean - owner: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - type: object - github: - properties: - allBranches: - type: boolean - api: - type: string - appSecretName: - type: string - organization: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - organization - type: object - gitlab: - properties: - allBranches: - type: boolean - api: - type: string - group: - type: string - includeSubgroups: - type: boolean - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - group - type: object - requeueAfterSeconds: - format: int64 - type: integer - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: type: string revisionHistoryLimit: format: int64 @@ -8825,404 +8275,2814 @@ spec: type: boolean name: type: string - value: + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: + allowEmpty: type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: + prune: type: boolean - releaseName: - type: string - skipCrds: + selfHeal: type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: - type: string type: object - kustomize: + managedNamespaceMetadata: properties: - commonAnnotations: + annotations: additionalProperties: type: string type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: + labels: additionalProperties: type: string type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object - path: + type: array + libs: + items: type: string - plugin: + type: array + tlas: + items: properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array + code: + type: boolean name: type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array + value: + type: string + required: + - name + - value type: object - ref: + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: type: string - repoURL: + path: type: string - targetRevision: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object - sources: - items: - properties: - chart: + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: + code: type: boolean - valueFiles: - items: - type: string - type: array - values: + name: type: string - version: + value: type: string + required: + - name + - value type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string path: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - repoURL: + value: type: string - targetRevision: + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: type: string - type: array - type: object - required: - - destination - - project + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string required: - - metadata - - spec + - repoURL type: object - type: object - selector: - properties: - matchExpressions: - items: + type: array + syncPolicy: + properties: + automated: properties: - key: - type: string - operator: - type: string - values: - items: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: type: string - type: array - required: - - key - - operator + type: object + labels: + additionalProperties: + type: string + type: object type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: object - type: array - mergeKeys: - items: - type: string - type: array + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer template: properties: metadata: @@ -9383,6 +11243,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -9560,6 +11423,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -9704,12 +11570,89 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - - generators - - mergeKeys + - configMapRef type: object pullRequest: properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object bitbucketServer: properties: api: @@ -9746,6 +11689,8 @@ spec: properties: branchMatch: type: string + targetBranchMatch: + type: string type: object type: array gitea: @@ -9805,6 +11750,8 @@ spec: properties: api: type: string + insecure: + type: boolean labels: items: type: string @@ -9989,6 +11936,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10166,6 +12116,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10313,6 +12266,26 @@ spec: type: object scmProvider: properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object azureDevOps: properties: accessTokenRef: @@ -10469,6 +12442,8 @@ spec: type: string includeSubgroups: type: boolean + insecure: + type: boolean tokenRef: properties: key: @@ -10645,6 +12620,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10822,6 +12800,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10966,6 +12947,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object type: object selector: properties: @@ -10994,6 +12979,10 @@ spec: type: array goTemplate: type: boolean + goTemplateOptions: + items: + type: string + type: array preservedFields: properties: annotations: @@ -11034,6 +13023,13 @@ spec: type: object syncPolicy: properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string preserveResourcesOnDeletion: type: boolean type: object @@ -11197,6 +13193,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -11374,6 +13373,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml index 5a6d15a02..79c4b81db 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applications.yaml @@ -287,8 +287,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -576,8 +583,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -982,8 +996,15 @@ spec: type: array values: description: Values specifies Helm values to be passed to - helm template, typically defined as a block + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1262,8 +1283,15 @@ spec: type: array values: description: Values specifies Helm values to be passed to - helm template, typically defined as a block + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1511,6 +1539,10 @@ spec: - type type: object type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string health: description: Health contains information about the application's current health status @@ -1690,8 +1722,15 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -1983,8 +2022,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -2421,8 +2468,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over + Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -2730,8 +2784,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined - as a block + as a block. ValuesObject takes precedence + over Values, so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3156,8 +3217,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3460,8 +3529,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over Values, + so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -3731,6 +3807,42 @@ spec: and must be set to the Kubernetes control plane API type: string type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted + managers. Fields mutated by those managers will take + precedence over the desired state defined in the SCM + and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array source: description: Source is a reference to the application's source used for comparison @@ -3869,8 +3981,16 @@ spec: type: array values: description: Values specifies Helm values to be passed - to helm template, typically defined as a block + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") @@ -4173,8 +4293,15 @@ spec: values: description: Values specifies Helm values to be passed to helm template, typically defined as - a block + a block. ValuesObject takes precedence over Values, + so use one or the other. type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true version: description: Version is the Helm version to use for templating ("3") diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml index 6e2a03d1b..0b351c7b8 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_applicationsets.yaml @@ -30,6 +30,8 @@ spec: type: object spec: properties: + applyNestedSelectors: + type: boolean generators: items: properties: @@ -225,6 +227,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -402,6 +407,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -738,6 +746,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -915,6 +926,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1255,6 +1269,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1432,6 +1449,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1576,6 +1596,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - repoURL - revision @@ -1748,6 +1772,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -1925,6 +1952,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2269,6 +2299,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2446,6 +2479,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2782,6 +2818,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -2959,6 +2998,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3299,6 +3341,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3476,6 +3521,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3620,6 +3668,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - repoURL - revision @@ -3792,6 +3844,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -3969,6 +4024,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4120,123 +4178,21 @@ spec: x-kubernetes-preserve-unknown-fields: true merge: x-kubernetes-preserve-unknown-fields: true - pullRequest: + plugin: properties: - bitbucketServer: - properties: - api: - type: string - basicAuth: - properties: - passwordRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - repo: - type: string - required: - - api - - project - - repo - type: object - filters: - items: - properties: - branchMatch: - type: string - type: object - type: array - gitea: - properties: - api: - type: string - insecure: - type: boolean - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - - repo - type: object - github: + configMapRef: properties: - api: - type: string - appSecretName: - type: string - labels: - items: - type: string - type: array - owner: - type: string - repo: + name: type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object required: - - owner - - repo + - name type: object - gitlab: + input: properties: - api: - type: string - labels: - items: - type: string - type: array - project: - type: string - pullRequestState: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true type: object - required: - - project type: object requeueAfterSeconds: format: int64 @@ -4401,6 +4357,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4578,6 +4537,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -4722,12 +4684,30 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef type: object - scmProvider: + pullRequest: properties: - azureDevOps: + azuredevops: properties: - accessTokenRef: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: properties: key: type: string @@ -4737,46 +4717,58 @@ spec: - key - secretName type: object - allBranches: - type: boolean - api: - type: string - organization: - type: string - teamProject: - type: string required: - - accessTokenRef - organization - - teamProject + - project + - repo type: object bitbucket: properties: - allBranches: - type: boolean - appPasswordRef: + api: + type: string + basicAuth: properties: - key: - type: string - secretName: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: type: string required: - - key - - secretName + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef type: object owner: type: string - user: + repo: type: string required: - - appPasswordRef - owner - - user + - repo type: object bitbucketServer: properties: - allBranches: - type: boolean api: type: string basicAuth: @@ -4799,41 +4791,32 @@ spec: type: object project: type: string + repo: + type: string required: - api - project + - repo type: object - cloneProtocol: - type: string filters: items: properties: branchMatch: type: string - labelMatch: - type: string - pathsDoNotExist: - items: - type: string - type: array - pathsExist: - items: - type: string - type: array - repositoryMatch: + targetBranchMatch: type: string type: object type: array gitea: properties: - allBranches: - type: boolean api: type: string insecure: type: boolean owner: type: string + repo: + type: string tokenRef: properties: key: @@ -4847,16 +4830,21 @@ spec: required: - api - owner + - repo type: object github: properties: - allBranches: - type: boolean api: type: string appSecretName: type: string - organization: + labels: + items: + type: string + type: array + owner: + type: string + repo: type: string tokenRef: properties: @@ -4869,18 +4857,23 @@ spec: - secretName type: object required: - - organization + - owner + - repo type: object gitlab: properties: - allBranches: - type: boolean api: type: string - group: - type: string - includeSubgroups: + insecure: type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string tokenRef: properties: key: @@ -4892,7 +4885,7 @@ spec: - secretName type: object required: - - group + - project type: object requeueAfterSeconds: format: int64 @@ -5057,6 +5050,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -5234,6 +5230,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -5379,562 +5378,212 @@ spec: - spec type: object type: object - selector: + scmProvider: properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: object - type: array - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: + awsCodeCommit: properties: - group: + allBranches: + type: boolean + region: type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: + role: type: string - managedFieldsManagers: + tagFilters: items: - type: string + properties: + key: + type: string + value: + type: string + required: + - key + type: object type: array - name: + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: type: string - namespace: + organization: + type: string + teamProject: type: string required: - - kind + - accessTokenRef + - organization + - teamProject type: object - type: array - info: - items: + bitbucket: properties: - name: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: type: string - value: + user: type: string required: - - name - - value + - appPasswordRef + - owner + - user type: object - type: array - project: - type: string - revisionHistoryLimit: - format: int64 - type: integer - source: - properties: - chart: - type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: - properties: - fileParameters: - items: + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: properties: - name: + key: type: string - path: + secretName: type: string + required: + - key + - secretName type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string type: array - ignoreMissingValueFiles: - type: boolean - parameters: + pathsExist: items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object + type: string type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: + repositoryMatch: type: string type: object - kustomize: - properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: + secretName: type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object - sources: - items: + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: properties: - chart: + allBranches: + type: boolean + api: type: string - directory: + appSecretName: + type: string + organization: + type: string + tokenRef: properties: - exclude: + key: type: string - include: + secretName: type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean + required: + - key + - secretName type: object - helm: + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: + key: type: string - version: + secretName: type: string + required: + - key + - secretName type: object - kustomize: + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: properties: - commonAnnotations: + annotations: additionalProperties: type: string type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: - type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: - type: string - type: object - path: - type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: - type: string - repoURL: - type: string - targetRevision: - type: string - required: - - repoURL - type: object - type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: - type: string - type: array - type: object - required: - - destination - - project - type: object - required: - - metadata - - spec - type: object - required: - - generators - type: object - merge: - properties: - generators: - items: - properties: - clusterDecisionResource: - properties: - configMapRef: - type: string - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - name: - type: string - requeueAfterSeconds: - format: int64 - type: integer - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: + finalizers: + items: type: string type: array labels: @@ -6085,6 +5734,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -6262,6 +5914,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -6410,560 +6065,568 @@ spec: additionalProperties: type: string type: object - required: - - configMapRef type: object - clusters: + selector: properties: - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: + matchExpressions: + items: + properties: + key: type: string - type: object - type: object - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: + operator: + type: string + values: + items: type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: - type: string - revisionHistoryLimit: - format: int64 - type: integer - source: - properties: - chart: - type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: + code: type: boolean - valueFiles: - items: - type: string - type: array - values: + name: type: string - version: + value: type: string + required: + - name + - value type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: + name: type: string - nameSuffix: - type: string - namespace: - type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string path: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - repoURL: + value: type: string - targetRevision: + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object - sources: - items: - properties: - chart: + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: type: string - directory: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - exclude: + code: + type: boolean + name: type: string - include: + value: type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean + required: + - name + - value type: object - helm: - properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: - type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: - type: string - type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object - path: + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + path: type: string - repoURL: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - targetRevision: + value: type: string - required: - - repoURL type: object type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: - type: string - type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: type: object - required: - - destination - - project + x-kubernetes-preserve-unknown-fields: true + version: + type: string type: object - required: - - metadata - - spec - type: object - values: - additionalProperties: - type: string - type: object - type: object - git: - properties: - directories: - items: - properties: - exclude: - type: boolean - path: - type: string - required: - - path - type: object - type: array - files: - items: - properties: - path: - type: string - required: - - path - type: object - type: array - pathParamPrefix: - type: string - repoURL: - type: string - requeueAfterSeconds: - format: int64 - type: integer - revision: - type: string - template: - properties: - metadata: + kustomize: properties: - annotations: + commonAnnotations: additionalProperties: type: string type: object - finalizers: + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: items: type: string type: array @@ -7115,6 +6778,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7292,6 +6958,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7436,18 +7105,38 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - - repoURL - - revision + - configMapRef type: object - list: + clusters: properties: - elements: - items: - x-kubernetes-preserve-unknown-fields: true - type: array - elementsYaml: - type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object template: properties: metadata: @@ -7608,6 +7297,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7785,6 +7477,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -7929,134 +7624,42 @@ spec: - metadata - spec type: object - required: - - elements + values: + additionalProperties: + type: string + type: object type: object - matrix: - x-kubernetes-preserve-unknown-fields: true - merge: - x-kubernetes-preserve-unknown-fields: true - pullRequest: + git: properties: - bitbucketServer: - properties: - api: - type: string - basicAuth: - properties: - passwordRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - repo: - type: string - required: - - api - - project - - repo - type: object - filters: + directories: items: properties: - branchMatch: + exclude: + type: boolean + path: type: string + required: + - path type: object type: array - gitea: - properties: - api: - type: string - insecure: - type: boolean - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - - repo - type: object - github: - properties: - api: - type: string - appSecretName: - type: string - labels: - items: - type: string - type: array - owner: - type: string - repo: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - owner - - repo - type: object - gitlab: - properties: - api: - type: string - labels: - items: + files: + items: + properties: + path: type: string - type: array - project: - type: string - pullRequestState: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - project - type: object + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string requeueAfterSeconds: format: int64 type: integer + revision: + type: string template: properties: metadata: @@ -8217,6 +7820,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -8394,6 +8000,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -8538,253 +8147,94 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision type: object - scmProvider: + list: properties: - azureDevOps: - properties: - accessTokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - allBranches: - type: boolean - api: - type: string - organization: - type: string - teamProject: - type: string - required: - - accessTokenRef - - organization - - teamProject - type: object - bitbucket: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: properties: - allBranches: - type: boolean - appPasswordRef: + metadata: properties: - key: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: type: string - secretName: + namespace: type: string - required: - - key - - secretName type: object - owner: - type: string - user: - type: string - required: - - appPasswordRef - - owner - - user - type: object - bitbucketServer: - properties: - allBranches: - type: boolean - api: - type: string - basicAuth: + spec: properties: - passwordRef: + destination: properties: - key: + name: type: string - secretName: + namespace: + type: string + server: type: string - required: - - key - - secretName type: object - username: - type: string - required: - - passwordRef - - username - type: object - project: - type: string - required: - - api - - project - type: object - cloneProtocol: - type: string - filters: - items: - properties: - branchMatch: - type: string - labelMatch: - type: string - pathsDoNotExist: - items: - type: string - type: array - pathsExist: - items: - type: string - type: array - repositoryMatch: - type: string - type: object - type: array - gitea: - properties: - allBranches: - type: boolean - api: - type: string - insecure: - type: boolean - owner: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - api - - owner - type: object - github: - properties: - allBranches: - type: boolean - api: - type: string - appSecretName: - type: string - organization: - type: string - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - organization - type: object - gitlab: - properties: - allBranches: - type: boolean - api: - type: string - group: - type: string - includeSubgroups: - type: boolean - tokenRef: - properties: - key: - type: string - secretName: - type: string - required: - - key - - secretName - type: object - required: - - group - type: object - requeueAfterSeconds: - format: int64 - type: integer - template: - properties: - metadata: - properties: - annotations: - additionalProperties: - type: string - type: object - finalizers: - items: - type: string - type: array - labels: - additionalProperties: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - spec: - properties: - destination: - properties: - name: - type: string - namespace: - type: string - server: - type: string - type: object - ignoreDifferences: - items: - properties: - group: - type: string - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - kind: - type: string - managedFieldsManagers: - items: - type: string - type: array - name: - type: string - namespace: - type: string - required: - - kind - type: object - type: array - info: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - project: + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: type: string revisionHistoryLimit: format: int64 @@ -8826,404 +8276,2814 @@ spec: type: boolean name: type: string - value: + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: + allowEmpty: type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: + prune: type: boolean - releaseName: - type: string - skipCrds: + selfHeal: type: boolean - valueFiles: - items: - type: string - type: array - values: - type: string - version: - type: string type: object - kustomize: + managedNamespaceMetadata: properties: - commonAnnotations: + annotations: additionalProperties: type: string type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: + labels: additionalProperties: type: string type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object - path: + type: array + libs: + items: type: string - plugin: + type: array + tlas: + items: properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array + code: + type: boolean name: type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array + value: + type: string + required: + - name + - value type: object - ref: + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: type: string - repoURL: + path: type: string - targetRevision: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object - sources: - items: - properties: - chart: + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: type: string - directory: - properties: - exclude: - type: string - include: - type: string - jsonnet: - properties: - extVars: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - libs: - items: - type: string - type: array - tlas: - items: - properties: - code: - type: boolean - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - type: object - recurse: - type: boolean - type: object - helm: + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: properties: - fileParameters: - items: - properties: - name: - type: string - path: - type: string - type: object - type: array - ignoreMissingValueFiles: - type: boolean - parameters: - items: - properties: - forceString: - type: boolean - name: - type: string - value: - type: string - type: object - type: array - passCredentials: - type: boolean - releaseName: - type: string - skipCrds: + code: type: boolean - valueFiles: - items: - type: string - type: array - values: + name: type: string - version: + value: type: string + required: + - name + - value type: object - kustomize: + type: array + libs: + items: + type: string + type: array + tlas: + items: properties: - commonAnnotations: - additionalProperties: - type: string - type: object - commonAnnotationsEnvsubst: - type: boolean - commonLabels: - additionalProperties: - type: string - type: object - forceCommonAnnotations: - type: boolean - forceCommonLabels: + code: type: boolean - images: - items: - type: string - type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: + name: type: string - replicas: - items: - properties: - count: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - name: - type: string - required: - - count - - name - type: object - type: array - version: + value: type: string + required: + - name + - value type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string path: type: string - plugin: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - name: - type: string - parameters: - items: - properties: - array: - items: - type: string - type: array - map: - additionalProperties: - type: string - type: object - name: - type: string - string: - type: string - type: object - type: array - type: object - ref: + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: type: string - repoURL: + value: type: string - targetRevision: + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: type: string required: - - repoURL + - count + - name type: object type: array - syncPolicy: - properties: - automated: - properties: - allowEmpty: - type: boolean - prune: - type: boolean - selfHeal: - type: boolean - type: object - managedNamespaceMetadata: - properties: - annotations: - additionalProperties: - type: string - type: object - labels: - additionalProperties: - type: string - type: object - type: object - retry: - properties: - backoff: - properties: - duration: - type: string - factor: - format: int64 - type: integer - maxDuration: - type: string - type: object - limit: - format: int64 - type: integer - type: object - syncOptions: - items: + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: type: string - type: array - type: object - required: - - destination - - project + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string required: - - metadata - - spec + - repoURL type: object - type: object - selector: - properties: - matchExpressions: - items: + type: array + syncPolicy: + properties: + automated: properties: - key: - type: string - operator: - type: string - values: - items: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: type: string - type: array - required: - - key - - operator + type: object + labels: + additionalProperties: + type: string + type: object type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - type: object - type: array - mergeKeys: - items: - type: string - type: array + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer template: properties: metadata: @@ -9384,6 +11244,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -9561,6 +11424,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -9705,12 +11571,89 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object required: - - generators - - mergeKeys + - configMapRef type: object pullRequest: properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object bitbucketServer: properties: api: @@ -9747,6 +11690,8 @@ spec: properties: branchMatch: type: string + targetBranchMatch: + type: string type: object type: array gitea: @@ -9806,6 +11751,8 @@ spec: properties: api: type: string + insecure: + type: boolean labels: items: type: string @@ -9990,6 +11937,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10167,6 +12117,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10314,6 +12267,26 @@ spec: type: object scmProvider: properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object azureDevOps: properties: accessTokenRef: @@ -10470,6 +12443,8 @@ spec: type: string includeSubgroups: type: boolean + insecure: + type: boolean tokenRef: properties: key: @@ -10646,6 +12621,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10823,6 +12801,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -10967,6 +12948,10 @@ spec: - metadata - spec type: object + values: + additionalProperties: + type: string + type: object type: object selector: properties: @@ -10995,6 +12980,10 @@ spec: type: array goTemplate: type: boolean + goTemplateOptions: + items: + type: string + type: array preservedFields: properties: annotations: @@ -11035,6 +13024,13 @@ spec: type: object syncPolicy: properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string preserveResourcesOnDeletion: type: boolean type: object @@ -11198,6 +13194,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object @@ -11375,6 +13374,9 @@ spec: type: array values: type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true version: type: string type: object diff --git a/go.mod b/go.mod index 6c65e1aa8..f8cb689dc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/argoproj-labs/argocd-operator go 1.19 require ( - github.com/argoproj/argo-cd/v2 v2.7.6 + github.com/argoproj/argo-cd/v2 v2.8.2 github.com/coreos/prometheus-operator v0.40.0 github.com/go-logr/logr v1.2.4 github.com/google/go-cmp v0.5.9 @@ -15,9 +15,9 @@ require ( github.com/openshift/client-go v0.0.0-20200325131901-f7baeb993edb github.com/operator-framework/operator-sdk v0.18.2 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.15.1 + github.com/prometheus/client_golang v1.16.0 github.com/sethvargo/go-password v0.2.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.4 golang.org/x/mod v0.10.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.27.1 @@ -52,7 +52,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/googleapis/gnostic v0.5.5 // indirect - github.com/imdario/mergo v0.3.15 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect @@ -62,21 +62,21 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.43.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/oauth2 v0.9.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index bf08d0f6c..759a9aa36 100644 --- a/go.sum +++ b/go.sum @@ -115,8 +115,8 @@ github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.m github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= 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/argoproj/argo-cd/v2 v2.7.6 h1:AKRQm0fLGgBmKQILrpc/2PZM2WYlfCP5tquU6DqDudU= -github.com/argoproj/argo-cd/v2 v2.7.6/go.mod h1:uRU//iTjnzlCs+hKOKo5Na2OZGNTlklnu/g9Wi4enh4= +github.com/argoproj/argo-cd/v2 v2.8.2 h1:NfFX2l5+YZXB2OTH4syVybX3/6kx+Q7bZkCgW0Hy7ZU= +github.com/argoproj/argo-cd/v2 v2.8.2/go.mod h1:Pkw7r6HKh5k/5Ynl4MvwCG79ktYBk+7PbJxCjXSlT30= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -658,8 +658,8 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.0/go.mod h1:BwN2XG2lMszOoquQaFdPET8FRQfrXiZsWmcMO9rkaVY= github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= @@ -973,8 +973,8 @@ github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -1013,8 +1013,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/prometheus v0.0.0-20180315085919-58e2a31db8de/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI= github.com/prometheus/prometheus v1.8.2-0.20200507164740-ecee9c8abfd1/go.mod h1:S5n0C6tSgdnwWshBUceRx5G1OsjLv/EeZ9t3wIfEtsY= @@ -1121,8 +1121,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/thanos-io/thanos v0.11.0/go.mod h1:N/Yes7J68KqvmY+xM6J5CJqEvWIvKSR5sqGtmuD6wDc= @@ -1270,8 +1271,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1372,8 +1373,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1386,8 +1387,8 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= +golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1501,14 +1502,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1518,8 +1519,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1736,8 +1737,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 8ddbce30cba63bcf7f26995801cb5f0308d50a53 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:24:17 +0530 Subject: [PATCH 14/94] chore: Update ArgoCD v1alpha1 deprecation message (#988) * Update ArgoCD v1alpha1 deprecation message Signed-off-by: Siddhesh Ghadi * Run code gen Signed-off-by: Siddhesh Ghadi --------- Signed-off-by: Siddhesh Ghadi --- api/v1alpha1/argocd_types.go | 2 +- bundle/manifests/argoproj.io_argocds.yaml | 4 +++- config/crd/bases/argoproj.io_argocds.yaml | 4 +++- .../argocd-operator/0.8.0/argoproj.io_argocds.yaml | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/api/v1alpha1/argocd_types.go b/api/v1alpha1/argocd_types.go index dfab608b5..ae5ef8326 100644 --- a/api/v1alpha1/argocd_types.go +++ b/api/v1alpha1/argocd_types.go @@ -36,7 +36,7 @@ func init() { // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // Important: Run "make" to regenerate code after modifying this file -// +kubebuilder:deprecatedversion:warning="ArgoCD v1alpha1 is deprecated, please use v1beta1 instead." +// +kubebuilder:deprecatedversion:warning="ArgoCD v1alpha1 version is deprecated and will be converted to v1beta1 automatically. Moving forward, please use v1beta1 as the ArgoCD API version." //+kubebuilder:object:root=true // ArgoCD is the Schema for the argocds API diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index 8d57db619..6ec5ab017 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -26,7 +26,9 @@ spec: scope: Namespaced versions: - deprecated: true - deprecationWarning: ArgoCD v1alpha1 is deprecated, please use v1beta1 instead. + deprecationWarning: ArgoCD v1alpha1 version is deprecated and will be converted + to v1beta1 automatically. Moving forward, please use v1beta1 as the ArgoCD API + version. name: v1alpha1 schema: openAPIV3Schema: diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 772cf9477..3674c2001 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -17,7 +17,9 @@ spec: scope: Namespaced versions: - deprecated: true - deprecationWarning: ArgoCD v1alpha1 is deprecated, please use v1beta1 instead. + deprecationWarning: ArgoCD v1alpha1 version is deprecated and will be converted + to v1beta1 automatically. Moving forward, please use v1beta1 as the ArgoCD API + version. name: v1alpha1 schema: openAPIV3Schema: diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index 8d57db619..6ec5ab017 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -26,7 +26,9 @@ spec: scope: Namespaced versions: - deprecated: true - deprecationWarning: ArgoCD v1alpha1 is deprecated, please use v1beta1 instead. + deprecationWarning: ArgoCD v1alpha1 version is deprecated and will be converted + to v1beta1 automatically. Moving forward, please use v1beta1 as the ArgoCD API + version. name: v1alpha1 schema: openAPIV3Schema: From 297702f3f3fb7da24264896a7510ff2cd36bc62b Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Wed, 6 Sep 2023 06:23:23 -0400 Subject: [PATCH 15/94] Add support for tls self signed certs in AppSet Gitlab SCM Provider (#985) * add support for tls self signed certs in AppSet Gitlab SCM Provider Signed-off-by: ishitasequeira * add e2e test Signed-off-by: ishitasequeira * add unit tests Signed-off-by: ishitasequeira * renamed field ScmRootCaPath to SCMRootCaPath Signed-off-by: ishitasequeira * Add documentation and address comments Signed-off-by: ishitasequeira * Address comments Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira --- api/v1beta1/argocd_types.go | 3 + bundle/manifests/argoproj.io_argocds.yaml | 5 ++ common/values.go | 3 + config/crd/bases/argoproj.io_argocds.yaml | 5 ++ controllers/argocd/applicationset.go | 39 +++++++++- controllers/argocd/applicationset_test.go | 36 +++++++-- controllers/argocd/argocd_controller.go | 2 +- controllers/argocd/configmap.go | 8 ++ controllers/argocd/custommapper.go | 28 +++++++ controllers/argocd/util.go | 8 +- .../0.8.0/argoproj.io_argocds.yaml | 5 ++ docs/reference/argocd.md | 19 +++++ .../01-assert.yaml | 75 +++++++++++++++++++ .../01-install.yaml | 56 ++++++++++++++ 14 files changed, 281 insertions(+), 11 deletions(-) create mode 100644 tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-assert.yaml create mode 100644 tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-install.yaml diff --git a/api/v1beta1/argocd_types.go b/api/v1beta1/argocd_types.go index 49af9f7cc..5c55851f4 100644 --- a/api/v1beta1/argocd_types.go +++ b/api/v1beta1/argocd_types.go @@ -159,6 +159,9 @@ type ArgoCDApplicationSet struct { LogLevel string `json:"logLevel,omitempty"` WebhookServer WebhookServerSpec `json:"webhookServer,omitempty"` + + // SCMRootCAConfigMap is the name of the config map that stores the Gitlab SCM Provider's TLS certificate which will be mounted on the ApplicationSet Controller (optional). + SCMRootCAConfigMap string `json:"scmRootCAConfigMap,omitempty"` } // ArgoCDCASpec defines the CA options for ArgCD. diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index 6ec5ab017..f0a7218e7 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -6655,6 +6655,11 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + scmRootCAConfigMap: + description: SCMRootCAConfigMap is the name of the config map + that stores the Gitlab SCM Provider's TLS certificate which + will be mounted on the ApplicationSet Controller (optional). + type: string version: description: Version is the Argo CD ApplicationSet image tag. (optional) diff --git a/common/values.go b/common/values.go index da6707919..9c3adda5c 100644 --- a/common/values.go +++ b/common/values.go @@ -77,6 +77,9 @@ const ( // ArgoCDTLSCertsConfigMapName is the upstream hard-coded TLS certificate data ConfigMap name. ArgoCDTLSCertsConfigMapName = "argocd-tls-certs-cm" + // ArgoCDAppSetGitlabSCMTLSCertsConfigMapName is the hard-coded ApplicationSet Gitlab SCM TLS certificate data ConfigMap name. + ArgoCDAppSetGitlabSCMTLSCertsConfigMapName = "argocd-appset-gitlab-scm-tls-certs-cm" + // ArgoCDRedisServerTLSSecretName is the name of the TLS secret for the redis-server ArgoCDRedisServerTLSSecretName = "argocd-operator-redis-tls" diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 3674c2001..c00bc7677 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -6646,6 +6646,11 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + scmRootCAConfigMap: + description: SCMRootCAConfigMap is the name of the config map + that stores the Gitlab SCM Provider's TLS certificate which + will be mounted on the ApplicationSet Controller (optional). + type: string version: description: Version is the Argo CD ApplicationSet image tag. (optional) diff --git a/controllers/argocd/applicationset.go b/controllers/argocd/applicationset.go index 3aa0e19ec..8e3f62205 100644 --- a/controllers/argocd/applicationset.go +++ b/controllers/argocd/applicationset.go @@ -33,6 +33,10 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argoutil" ) +const ( + ApplicationSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" +) + // getArgoApplicationSetCommand will return the command for the ArgoCD ApplicationSet component. func getArgoApplicationSetCommand(cr *argoproj.ArgoCD) []string { cmd := make([]string, 0) @@ -46,6 +50,11 @@ func getArgoApplicationSetCommand(cr *argoproj.ArgoCD) []string { cmd = append(cmd, "--loglevel") cmd = append(cmd, getLogLevel(cr.Spec.ApplicationSet.LogLevel)) + if cr.Spec.ApplicationSet.SCMRootCAConfigMap != "" { + cmd = append(cmd, "--scm-root-ca-path") + cmd = append(cmd, ApplicationSetGitlabSCMTlsCertPath) + } + // ApplicationSet command arguments provided by the user extraArgs := cr.Spec.ApplicationSet.ExtraCommandArgs err := isMergable(extraArgs, cmd) @@ -144,9 +153,26 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, }, }, } + addSCMGitlabVolumeMount := false + if scmRootCAConfigMapName := getSCMRootCAConfigMapName(cr); scmRootCAConfigMapName != "" { + cm := newConfigMapWithName(scmRootCAConfigMapName, cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, cr.Spec.ApplicationSet.SCMRootCAConfigMap, cm) { + addSCMGitlabVolumeMount = true + podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{ + Name: "appset-gitlab-scm-tls-cert", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, + }, + }, + }, + }) + } + } podSpec.Containers = []corev1.Container{ - applicationSetContainer(cr), + applicationSetContainer(cr, addSCMGitlabVolumeMount), } AddSeccompProfileForOpenShift(r.Client, podSpec) @@ -185,7 +211,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, } -func applicationSetContainer(cr *argoproj.ArgoCD) corev1.Container { +func applicationSetContainer(cr *argoproj.ArgoCD, addSCMGitlabVolumeMount bool) corev1.Container { // Global proxy env vars go first appSetEnv := []corev1.EnvVar{{ Name: "NAMESPACE", @@ -202,7 +228,7 @@ func applicationSetContainer(cr *argoproj.ArgoCD) corev1.Container { // Environment specified in the CR take precedence over everything else appSetEnv = argoutil.EnvMerge(appSetEnv, proxyEnvVars(), false) - return corev1.Container{ + container := corev1.Container{ Command: getArgoApplicationSetCommand(cr), Env: appSetEnv, Image: getApplicationSetContainerImage(cr), @@ -252,6 +278,13 @@ func applicationSetContainer(cr *argoproj.ArgoCD) corev1.Container { RunAsNonRoot: boolPtr(true), }, } + if addSCMGitlabVolumeMount { + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: "appset-gitlab-scm-tls-cert", + MountPath: ApplicationSetGitlabSCMTlsCertPath, + }) + } + return container } func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { diff --git a/controllers/argocd/applicationset_test.go b/controllers/argocd/applicationset_test.go index d09f29d3f..9a7022baf 100644 --- a/controllers/argocd/applicationset_test.go +++ b/controllers/argocd/applicationset_test.go @@ -27,6 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -92,14 +93,14 @@ func TestReconcileApplicationSet_CreateDeployments(t *testing.T) { deployment)) // Ensure the created Deployment has the expected properties - checkExpectedDeploymentValues(t, deployment, &sa, a) + checkExpectedDeploymentValues(t, r, deployment, &sa, a) } -func checkExpectedDeploymentValues(t *testing.T, deployment *appsv1.Deployment, sa *corev1.ServiceAccount, a *argoproj.ArgoCD) { +func checkExpectedDeploymentValues(t *testing.T, r *ReconcileArgoCD, deployment *appsv1.Deployment, sa *corev1.ServiceAccount, a *argoproj.ArgoCD) { assert.Equal(t, deployment.Spec.Template.Spec.ServiceAccountName, sa.ObjectMeta.Name) appsetAssertExpectedLabels(t, &deployment.ObjectMeta) - want := []corev1.Container{applicationSetContainer(a)} + want := []corev1.Container{applicationSetContainer(a, false)} if diff := cmp.Diff(want, deployment.Spec.Template.Spec.Containers); diff != "" { t.Fatalf("failed to reconcile applicationset-controller deployment containers:\n%s", diff) @@ -150,6 +151,19 @@ func checkExpectedDeploymentValues(t *testing.T, deployment *appsv1.Deployment, }, } + if a.Spec.ApplicationSet.SCMRootCAConfigMap != "" && argoutil.IsObjectFound(r.Client, a.Namespace, common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, a) { + volumes = append(volumes, corev1.Volume{ + Name: "appset-gitlab-scm-tls-cert", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, + }, + }, + }, + }) + } + if diff := cmp.Diff(volumes, deployment.Spec.Template.Spec.Volumes); diff != "" { t.Fatalf("failed to reconcile applicationset-controller deployment volumes:\n%s", diff) } @@ -261,7 +275,7 @@ func TestReconcileApplicationSet_UpdateExistingDeployments(t *testing.T) { deployment)) // Ensure the updated Deployment has the expected properties - checkExpectedDeploymentValues(t, deployment, &sa, a) + checkExpectedDeploymentValues(t, r, deployment, &sa, a) } @@ -287,7 +301,7 @@ func TestReconcileApplicationSet_Deployments_resourceRequirements(t *testing.T) assert.Equal(t, deployment.Spec.Template.Spec.ServiceAccountName, sa.ObjectMeta.Name) appsetAssertExpectedLabels(t, &deployment.ObjectMeta) - containerWant := []corev1.Container{applicationSetContainer(a)} + containerWant := []corev1.Container{applicationSetContainer(a, false)} if diff := cmp.Diff(containerWant, deployment.Spec.Template.Spec.Containers); diff != "" { t.Fatalf("failed to reconcile argocd-server deployment:\n%s", diff) @@ -346,6 +360,14 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { envVars: map[string]string{common.ArgoCDImageEnvName: "custom-env-image"}, expectedContainerImage: "custom-image:custom-version", }, + { + name: "ensure scm tls cert mount is present", + appSetField: &argoproj.ArgoCDApplicationSet{ + SCMRootCAConfigMap: "test-scm-tls-mount", + }, + envVars: map[string]string{common.ArgoCDImageEnvName: "custom-env-image"}, + expectedContainerImage: "custom-env-image", + }, } for _, test := range tests { @@ -357,6 +379,8 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { a := makeTestArgoCD() r := makeTestReconciler(t, a) + cm := newConfigMapWithName(getCAConfigMapName(a), a) + r.Client.Create(context.Background(), cm, &client.CreateOptions{}) a.Spec.ApplicationSet = test.appSetField @@ -374,7 +398,7 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { specImage := deployment.Spec.Template.Spec.Containers[0].Image assert.Equal(t, test.expectedContainerImage, specImage) - + checkExpectedDeploymentValues(t, r, deployment, &sa, a) }) } diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 642dc405c..85cd17e48 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -198,6 +198,6 @@ func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) ( // SetupWithManager sets up the controller with the Manager. func (r *ReconcileArgoCD) SetupWithManager(mgr ctrl.Manager) error { bldr := ctrl.NewControllerManagedBy(mgr) - r.setResourceWatches(bldr, r.clusterResourceMapper, r.tlsSecretMapper, r.namespaceResourceMapper, r.clusterSecretResourceMapper) + r.setResourceWatches(bldr, r.clusterResourceMapper, r.tlsSecretMapper, r.namespaceResourceMapper, r.clusterSecretResourceMapper, r.applicationSetSCMTLSConfigMapMapper) return bldr.Complete(r) } diff --git a/controllers/argocd/configmap.go b/controllers/argocd/configmap.go index 5d64fab95..e8f6e5a51 100644 --- a/controllers/argocd/configmap.go +++ b/controllers/argocd/configmap.go @@ -63,6 +63,14 @@ func getCAConfigMapName(cr *argoproj.ArgoCD) string { return nameWithSuffix(common.ArgoCDCASuffix, cr) } +// getSCMRootCAConfigMapName will return the SCMRootCA ConfigMap name for the given ArgoCD ApplicationSet Controller. +func getSCMRootCAConfigMapName(cr *argoproj.ArgoCD) string { + if cr.Spec.ApplicationSet.SCMRootCAConfigMap != "" && len(cr.Spec.ApplicationSet.SCMRootCAConfigMap) > 0 { + return cr.Spec.ApplicationSet.SCMRootCAConfigMap + } + return "" +} + // getConfigManagementPlugins will return the config management plugins for the given ArgoCD. func getConfigManagementPlugins(cr *argoproj.ArgoCD) string { plugins := common.ArgoCDDefaultConfigManagementPlugins diff --git a/controllers/argocd/custommapper.go b/controllers/argocd/custommapper.go index 502373571..f97e6db19 100644 --- a/controllers/argocd/custommapper.go +++ b/controllers/argocd/custommapper.go @@ -182,3 +182,31 @@ func (r *ReconcileArgoCD) clusterSecretResourceMapper(o client.Object) []reconci return result } + +// applicationSetSCMTLSConfigMapMapper maps a watch event on a configmap with name "argocd-appset-gitlab-scm-tls-certs-cm", +// back to the ArgoCD object that we want to reconcile. +func (r *ReconcileArgoCD) applicationSetSCMTLSConfigMapMapper(o client.Object) []reconcile.Request { + var result = []reconcile.Request{} + + if o.GetName() == common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName { + argocds := &argoproj.ArgoCDList{} + if err := r.Client.List(context.TODO(), argocds, &client.ListOptions{Namespace: o.GetNamespace()}); err != nil { + return result + } + + if len(argocds.Items) != 1 { + return result + } + + argocd := argocds.Items[0] + namespacedName := client.ObjectKey{ + Name: argocd.Name, + Namespace: argocd.Namespace, + } + result = []reconcile.Request{ + {NamespacedName: namespacedName}, + } + } + + return result +} diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index 687189b6c..17680c131 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -931,7 +931,7 @@ func removeString(slice []string, s string) []string { } // setResourceWatches will register Watches for each of the supported Resources. -func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResourceMapper, tlsSecretMapper, namespaceResourceMapper, clusterSecretResourceMapper handler.MapFunc) *builder.Builder { +func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResourceMapper, tlsSecretMapper, namespaceResourceMapper, clusterSecretResourceMapper, applicationSetGitlabSCMTLSConfigMapMapper handler.MapFunc) *builder.Builder { deploymentConfigPred := predicate.Funcs{ UpdateFunc: func(e event.UpdateEvent) bool { @@ -1046,12 +1046,18 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou clusterSecretResourceHandler := handler.EnqueueRequestsFromMapFunc(clusterSecretResourceMapper) + appSetGitlabSCMTLSConfigMapHandler := handler.EnqueueRequestsFromMapFunc(applicationSetGitlabSCMTLSConfigMapMapper) + tlsSecretHandler := handler.EnqueueRequestsFromMapFunc(tlsSecretMapper) bldr.Watches(&source.Kind{Type: &v1.ClusterRoleBinding{}}, clusterResourceHandler) bldr.Watches(&source.Kind{Type: &v1.ClusterRole{}}, clusterResourceHandler) + bldr.Watches(&source.Kind{Type: &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ + Name: common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, + }}}, appSetGitlabSCMTLSConfigMapHandler) + // Watch for secrets of type TLS that might be created by external processes bldr.Watches(&source.Kind{Type: &corev1.Secret{Type: corev1.SecretTypeTLS}}, tlsSecretHandler) diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index 6ec5ab017..f0a7218e7 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -6655,6 +6655,11 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + scmRootCAConfigMap: + description: SCMRootCAConfigMap is the name of the config map + that stores the Gitlab SCM Provider's TLS certificate which + will be mounted on the ApplicationSet Controller (optional). + type: string version: description: Version is the Argo CD ApplicationSet image tag. (optional) diff --git a/docs/reference/argocd.md b/docs/reference/argocd.md index 53112b10e..4bb5f1b74 100644 --- a/docs/reference/argocd.md +++ b/docs/reference/argocd.md @@ -85,6 +85,7 @@ Resources | [Empty] | The container compute resources. LogLevel | info | The log level to be used by the ArgoCD Application Controller component. Valid options are debug, info, error, and warn. LogFormat | text | The log format to be used by the ArgoCD Application Controller component. Valid options are text or json. ParallelismLimit | 10 | The kubectl parallelism limit to set for the controller (`--kubectl-parallelism-limit` flag) +SCMRootCAConfigMap (#add-tls-certificate-for-gitlab-scm-provider-to-applicationsets-controller) | [Empty] | The name of the config map that stores the Gitlab SCM Provider's TLS certificate which will be mounted on the ApplicationSet Controller at `"/app/tls/scm/cert"` path. ### ApplicationSet Controller Example @@ -119,6 +120,24 @@ spec: - bar ``` +### Add Self signed TLS Certificate for Gitlab SCM Provider to ApplicationSets Controller + +ApplicationSetController added a new option `--scm-root-ca-path` and expects the self-signed TLS certificate to be mounted on the path specified and to be used for Gitlab SCM Provider and Gitlab Pull Request Provider. To set this option, you can store the certificate in the config map and specify the config map name using `spec.applicationSet.SCMRootCAConfigMap` in ArgoCD CR. When the parameter `spec.applicationSet.SCMRootCAConfigMap` is set in ArgoCD CR, the operator checks for ConfigMap in the same namespace as the ArgoCD instance and mounts the Certificate stored in ConfigMap to ApplicationSet Controller pods at the path `/app/tls/scm/cert`. + +Below example shows how a user can add scmRootCaPath to the ApplicationSet controller. +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: example-argocd + labels: + example: applicationset +spec: + applicationSet: + SCMRootCAConfigMap: example-gitlab-scm-tls-cert +``` + + ## Config Management Plugins Configuration to add a config management plugin. This property maps directly to the `configManagementPlugins` field in the `argocd-cm` ConfigMap. diff --git a/tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-assert.yaml b/tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-assert.yaml new file mode 100644 index 000000000..38eee67c7 --- /dev/null +++ b/tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-assert.yaml @@ -0,0 +1,75 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +timeout: 120 +--- +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + namespace: test-1-32-appsets-scm-tls-mount +spec: + applicationSet: + scmRootCAConfigMap: test-1-32-appsets-scm-tls-cm +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-applicationset-controller + namespace: test-1-32-appsets-scm-tls-mount + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: argocd + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd-applicationset +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-applicationset-controller + template: + spec: + containers: + - command: + - entrypoint.sh + - argocd-applicationset-controller + - --argocd-repo-server + - argocd-repo-server.test-1-32-appsets-scm-tls-mount.svc.cluster.local:8081 + - --loglevel + - info + - --scm-root-ca-path + - /app/tls/scm/cert + volumeMounts: + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + - mountPath: /app/tls/scm/cert + name: appset-gitlab-scm-tls-cert + volumes: + - configMap: + defaultMode: 420 + name: argocd-ssh-known-hosts-cm + name: ssh-known-hosts + - configMap: + defaultMode: 420 + name: argocd-tls-certs-cm + name: tls-certs + - configMap: + defaultMode: 420 + name: argocd-gpg-keys-cm + name: gpg-keys + - emptyDir: {} + name: gpg-keyring + - emptyDir: {} + name: tmp + - configMap: + defaultMode: 420 + name: argocd-appset-gitlab-scm-tls-certs-cm + name: appset-gitlab-scm-tls-cert diff --git a/tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-install.yaml b/tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-install.yaml new file mode 100644 index 000000000..8895fecb2 --- /dev/null +++ b/tests/k8s/1-033_validate_applicationset_tls_scm_volume_mount/01-install.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: test-1-32-appsets-scm-tls-mount +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: test-1-32-appsets-scm-tls-cm + namespace: test-1-32-appsets-scm-tls-mount +data: + cert: | + -----BEGIN CERTIFICATE----- + AIIEBCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL + BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE + BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0 + c3VpdGUxGDAWBrNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda + Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT + YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES + MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi + MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5 + NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc + CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u + P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G + ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+ + YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E + Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko + Ml1L4zCU+xEsMcvb1iQ2n7PZdacqhkFRUVVVmJ56th8aYyX7KNX6M9CD+kMpNm6J + kKC1li/Iy+RI138bAvaFplajMF551kt44dSvIoJIbTr1LigudzWPqk31QaZXV/4u + kD1n4p/XMc9HYU/was/CmQBFqmIZedTLTtK7clkuFN6wbwzdo1wmUNgnySQuMacO + gxhHxxzRWxd24uLyk9Px+9U3BfVPaRLiOPaPoC58lyVOykjSgfpgbus7JS69fCq7 + bEH4Jatp/10zkco+UQIDAQABo1MwUTAdBgNVHQ4EFgQUjXH6PHi92y4C4hQpey86 + r6+x1ewwHwYDVR0jBBgwFoAUjXH6PHi92y4C4hQpey86r6+x1ewwDwYDVR0TAQH/ + BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFE4SdKsX9UsLy+Z0xuHSxhTd0jfn + Iih5mtzb8CDNO5oTw4z0aMeAvpsUvjJ/XjgxnkiRACXh7K9hsG2r+ageRWGevyvx + CaRXFbherV1kTnZw4Y9/pgZTYVWs9jlqFOppz5sStkfjsDQ5lmPJGDii/StENAz2 + XmtiPOgfG9Upb0GAJBCuKnrU9bIcT4L20gd2F4Y14ccyjlf8UiUi192IX6yM9OjT + +TuXwZgqnTOq6piVgr+FTSa24qSvaXb5z/mJDLlk23npecTouLg83TNSn3R6fYQr + d/Y9eXuUJ8U7/qTh2Ulz071AO9KzPOmleYPTx4Xty4xAtWi1QE5NHW9/Ajlv5OtO + OnMNWIs7ssDJBsB7VFC8hcwf79jz7kC0xmQqDfw51Xhhk04kla+v+HZcFW2AO9so + 6ZdVHHQnIbJa7yQJKZ+hK49IOoBR6JgdB5kymoplLLiuqZSYTcwSBZ72FYTm3iAr + jzvt1hxpxVDmXvRnkhRrIRhK4QgJL0jRmirBjDY+PYYd7bdRIjN7WNZLFsgplnS8 + 9w6CwG32pRlm0c8kkiQ7FXA6BYCqOsDI8f1VGQv331OpR2Ck+FTv+L7DAmg6l37W + AIIEBCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL + XWyb96wrUlv+E8I= + -----END CERTIFICATE----- + +--- +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd + namespace: test-1-32-appsets-scm-tls-mount +spec: + applicationSet: + scmRootCAConfigMap: test-1-32-appsets-scm-tls-cm \ No newline at end of file From 64d5bb21b6eaa1d6a862a32e930c003d77376b36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 00:00:23 +0530 Subject: [PATCH 16/94] chore(deps): bump github.com/argoproj/argo-cd/v2 from 2.8.2 to 2.8.3 (#992) Bumps [github.com/argoproj/argo-cd/v2](https://github.com/argoproj/argo-cd) from 2.8.2 to 2.8.3. - [Release notes](https://github.com/argoproj/argo-cd/releases) - [Changelog](https://github.com/argoproj/argo-cd/blob/master/CHANGELOG.md) - [Commits](https://github.com/argoproj/argo-cd/compare/v2.8.2...v2.8.3) --- updated-dependencies: - dependency-name: github.com/argoproj/argo-cd/v2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f8cb689dc..471d24fa6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/argoproj-labs/argocd-operator go 1.19 require ( - github.com/argoproj/argo-cd/v2 v2.8.2 + github.com/argoproj/argo-cd/v2 v2.8.3 github.com/coreos/prometheus-operator v0.40.0 github.com/go-logr/logr v1.2.4 github.com/google/go-cmp v0.5.9 diff --git a/go.sum b/go.sum index 759a9aa36..5e45feb61 100644 --- a/go.sum +++ b/go.sum @@ -115,8 +115,8 @@ github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.m github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= 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/argoproj/argo-cd/v2 v2.8.2 h1:NfFX2l5+YZXB2OTH4syVybX3/6kx+Q7bZkCgW0Hy7ZU= -github.com/argoproj/argo-cd/v2 v2.8.2/go.mod h1:Pkw7r6HKh5k/5Ynl4MvwCG79ktYBk+7PbJxCjXSlT30= +github.com/argoproj/argo-cd/v2 v2.8.3 h1:ybJ7eNoP7/u5Vqncais6WeVRBEGmZmriAIwLEKmWHIA= +github.com/argoproj/argo-cd/v2 v2.8.3/go.mod h1:Pkw7r6HKh5k/5Ynl4MvwCG79ktYBk+7PbJxCjXSlT30= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= From 91bf13127dd70bc853096ee3ee72892ebc6c535d Mon Sep 17 00:00:00 2001 From: Abhishek Veeramalla Date: Tue, 12 Sep 2023 00:33:32 +0530 Subject: [PATCH 17/94] feat: pick up argo cd v2.8.3 (#993) Signed-off-by: iam-veeramalla --- build/util/Dockerfile | 4 ++-- common/defaults.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/util/Dockerfile b/build/util/Dockerfile index f4475c941..72bf1fae5 100644 --- a/build/util/Dockerfile +++ b/build/util/Dockerfile @@ -1,5 +1,5 @@ -# Argo CD v2.8.2 -FROM quay.io/argoproj/argocd@sha256:14e293cd7e35169c45ec51cccdabb80da72c434d7e16d60d3de2ce3a23f08c4b as argocd +# Argo CD v2.8.3 +FROM quay.io/argoproj/argocd@sha256:d40da8f5747415eb7f9b5c2d9b645aecd423888cad9b36e4f986bff8ecf0a786 as argocd # Final Image FROM docker.io/library/ubuntu:22.04 diff --git a/common/defaults.go b/common/defaults.go index 9bb236411..4a420e02f 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -61,7 +61,7 @@ const ( ArgoCDDefaultArgoImage = "quay.io/argoproj/argocd" // ArgoCDDefaultArgoVersion is the Argo CD container image digest to use when version not specified. - ArgoCDDefaultArgoVersion = "sha256:14e293cd7e35169c45ec51cccdabb80da72c434d7e16d60d3de2ce3a23f08c4b" // v2.8.2 + ArgoCDDefaultArgoVersion = "sha256:d40da8f5747415eb7f9b5c2d9b645aecd423888cad9b36e4f986bff8ecf0a786" // v2.8.3 // ArgoCDDefaultBackupKeyLength is the length of the generated default backup key. ArgoCDDefaultBackupKeyLength = 32 From cd7a54bb43ef333aff430acbec52d428adb3c270 Mon Sep 17 00:00:00 2001 From: Minchao Date: Mon, 25 Sep 2023 09:39:36 -0500 Subject: [PATCH 18/94] fix: replace deprecated syntax in kustomization.yaml (#1000) Signed-off-by: minchao --- config/crd/kustomization.yaml | 10 +++++----- config/default/kustomization.yaml | 12 ++++++------ docs/install/manual.md | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index affcaaf1f..d64b76627 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -10,17 +10,17 @@ resources: #+kubebuilder:scaffold:crdkustomizeresource -patchesStrategicMerge: +patches: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -- patches/webhook_in_argocds.yaml -#- patches/webhook_in_argocdexports.yaml +- path: patches/webhook_in_argocds.yaml +#- path: patches/webhook_in_argocdexports.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -- patches/cainjection_in_argocds.yaml -#- patches/cainjection_in_argocdexports.yaml +- path: patches/cainjection_in_argocds.yaml +#- path: patches/cainjection_in_argocdexports.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 89a72e9b2..2bd4e09fd 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -12,7 +12,7 @@ namePrefix: argocd-operator- #commonLabels: # someName: someValue -bases: +resources: - ../crd - ../rbac - ../manager @@ -24,24 +24,24 @@ bases: # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. # - ../prometheus -patchesStrategicMerge: +patches: # Protect the /metrics endpoint by putting it behind auth. # If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line. -# - manager_auth_proxy_patch.yaml +#- path: manager_auth_proxy_patch.yaml # Mount the controller config file for loading manager configurations # through a ComponentConfig type -#- manager_config_patch.yaml +#- path: manager_config_patch.yaml # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -- manager_webhook_patch.yaml +- path: manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. # 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml +#- path: webhookcainjection_patch.yaml # the following config is for teaching kustomize how to do var substitution vars: diff --git a/docs/install/manual.md b/docs/install/manual.md index 79fb7cdc3..99a975c34 100644 --- a/docs/install/manual.md +++ b/docs/install/manual.md @@ -50,9 +50,9 @@ metadata: cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) ``` -Enable `../certmanager` directory under the `bases` section in `config/default/kustomization.yaml` file. +Enable `../certmanager` directory under the `resources` section in `config/default/kustomization.yaml` file. ```yaml -bases: +resources: ..... - ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. From aa6ab4eadc20cddbcbdd94efdc4f055723c1ff7b Mon Sep 17 00:00:00 2001 From: Suraj yadav Date: Mon, 25 Sep 2023 20:48:22 +0530 Subject: [PATCH 19/94] Missing syntax-highlighting, toggle button for screen mode in argocd-operator docs (#1002) * Update requirements.txt added markdown= 3.3.7 and markdown-include=0.6.0 Signed-off-by: Surajyadav * Delete docs/assets/extra.css deleted extra.css Signed-off-by: Surajyadav * Update mkdocs.yml added markdown_extension markdown_include with codehighlight and toggle for screen mode Signed-off-by: Surajyadav * Update mkdocs.yml Signed-off-by: Surajyadav --------- Signed-off-by: Surajyadav --- docs/assets/extra.css | 10 ---------- docs/requirements.txt | 2 ++ mkdocs.yml | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 docs/assets/extra.css diff --git a/docs/assets/extra.css b/docs/assets/extra.css deleted file mode 100644 index 055aff201..000000000 --- a/docs/assets/extra.css +++ /dev/null @@ -1,10 +0,0 @@ -.codehilite { - background-color: hsla(0,0%,92.5%,.5); - overflow: auto; - -webkit-overflow-scrolling: touch; -} - -.codehilite pre { - background-color: transparent; - padding: .525rem .6rem; -} diff --git a/docs/requirements.txt b/docs/requirements.txt index d84098727..64e8ab971 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,6 @@ mkdocs==1.2.3 mkdocs-material==7.1.7 +markdown_include==0.6.0 pygments==2.15.0 jinja2===3.0.3 +markdown==3.3.7 diff --git a/mkdocs.yml b/mkdocs.yml index 0ff6cb746..e52876c65 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,14 +5,25 @@ strict: true theme: name: material palette: + - media: '(prefers-color-scheme: light)' primary: teal + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: '(prefers-color-scheme: dark)' + primary: teal + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to light mode font: text: 'Work Sans' logo: 'assets/logo.png' -extra_css: - - 'assets/extra.css' markdown_extensions: -- codehilite +- markdown_include.include +- codehilite: + css_class: highlight - admonition - toc: permalink: true From 75d6cf4d3e7f0c1f5e024a43e669bba4e4dae7a5 Mon Sep 17 00:00:00 2001 From: Abhishek Veeramalla Date: Tue, 26 Sep 2023 11:37:12 +0530 Subject: [PATCH 20/94] fix: keycloak probes failure and intermittent perforamance issues (#1007) * fix: keycloak probes failure results in pod crash Signed-off-by: iam-veeramalla * fix: use latest keycloak image to handle performance issue Signed-off-by: iam-veeramalla --------- Signed-off-by: iam-veeramalla --- common/defaults.go | 4 ++-- controllers/argocd/keycloak.go | 7 ++++--- controllers/argocd/keycloak_test.go | 4 ++-- tests/ocp/1-001_validate_rhsso/01-assert.yaml | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/common/defaults.go b/common/defaults.go index 4a420e02f..2912428e8 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -186,8 +186,8 @@ const ( ArgoCDKeycloakImageForOpenShift = "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8" // ArgoCDKeycloakVersionForOpenShift is the default Keycloak version used for the OpenShift platform when not specified. - // Version: 7.6-25 - ArgoCDKeycloakVersionForOpenShift = "sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d" + // Version: 7.6-32 + ArgoCDKeycloakVersionForOpenShift = "sha256:ec9f60018694dcc5d431ba47d5536b761b71cb3f66684978fe6bb74c157679ac" // ArgoCDDefaultOIDCConfig is the default OIDC configuration. ArgoCDDefaultOIDCConfig = "" diff --git a/controllers/argocd/keycloak.go b/controllers/argocd/keycloak.go index 0d91cd9c4..f4a025488 100644 --- a/controllers/argocd/keycloak.go +++ b/controllers/argocd/keycloak.go @@ -282,7 +282,7 @@ func getKeycloakContainer(cr *argoproj.ArgoCD) corev1.Container { Image: getKeycloakContainerImage(cr), ImagePullPolicy: "Always", LivenessProbe: &corev1.Probe{ - TimeoutSeconds: 120, + TimeoutSeconds: 240, ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ Command: []string{ @@ -292,7 +292,7 @@ func getKeycloakContainer(cr *argoproj.ArgoCD) corev1.Container { }, }, }, - InitialDelaySeconds: 60, + InitialDelaySeconds: 120, }, Name: "${APPLICATION_NAME}", Ports: []corev1.ContainerPort{ @@ -302,7 +302,8 @@ func getKeycloakContainer(cr *argoproj.ArgoCD) corev1.Container { {ContainerPort: 8888, Name: "ping", Protocol: "TCP"}, }, ReadinessProbe: &corev1.Probe{ - TimeoutSeconds: 120, + TimeoutSeconds: 240, + InitialDelaySeconds: 120, ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ Command: []string{ diff --git a/controllers/argocd/keycloak_test.go b/controllers/argocd/keycloak_test.go index d89ccb152..c6d65fdda 100644 --- a/controllers/argocd/keycloak_test.go +++ b/controllers/argocd/keycloak_test.go @@ -113,7 +113,7 @@ func TestKeycloakContainerImage(t *testing.T) { }), updateCrFunc: nil, templateAPIFound: true, - wantContainerImage: "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d", + wantContainerImage: "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:ec9f60018694dcc5d431ba47d5536b761b71cb3f66684978fe6bb74c157679ac", }, { name: "ArgoCDKeycloakImageEnvName env var set", @@ -249,7 +249,7 @@ func TestNewKeycloakTemplate_testKeycloakContainer(t *testing.T) { } kc := getKeycloakContainer(a) assert.Equal(t, - "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d", kc.Image) + "registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:ec9f60018694dcc5d431ba47d5536b761b71cb3f66684978fe6bb74c157679ac", kc.Image) assert.Equal(t, corev1.PullAlways, kc.ImagePullPolicy) assert.Equal(t, "${APPLICATION_NAME}", kc.Name) } diff --git a/tests/ocp/1-001_validate_rhsso/01-assert.yaml b/tests/ocp/1-001_validate_rhsso/01-assert.yaml index c0586f98b..5c2173e61 100644 --- a/tests/ocp/1-001_validate_rhsso/01-assert.yaml +++ b/tests/ocp/1-001_validate_rhsso/01-assert.yaml @@ -33,7 +33,7 @@ spec: name: keycloak spec: containers: - - image: registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:bb6dc12a49370ba6baa40cfa064238cddcfd1edb22c37dcdf53d331c0f7ee15d + - image: registry.redhat.io/rh-sso-7/sso76-openshift-rhel8@sha256:ec9f60018694dcc5d431ba47d5536b761b71cb3f66684978fe6bb74c157679ac resources: limits: cpu: "1" From edf628db4d5f1da239b2ec2fe927fa5430fe40c5 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Fri, 29 Sep 2023 14:37:48 -0400 Subject: [PATCH 21/94] Implemented service, servicemonitor and tlssecret Signed-off-by: Yi Cai --- common/envVars.go | 2 + common/keys.go | 2 + common/values.go | 13 +- controllers/argocd/appcontroller/constants.go | 5 + controllers/argocd/argocdcommon/argohelper.go | 45 ++ controllers/argocd/redis/constants.go | 5 + controllers/argocd/redis/redis.go | 2 + controllers/argocd/redis/util.go | 62 +++ controllers/argocd/reposerver/constants.go | 11 + controllers/argocd/reposerver/deployment.go | 387 ++++++++++++++++++ controllers/argocd/reposerver/reposerver.go | 55 ++- controllers/argocd/reposerver/service.go | 107 +++++ .../argocd/reposerver/servicemonitor.go | 69 ++++ controllers/argocd/reposerver/tlssecret.go | 107 +++++ controllers/argocd/reposerver/util.go | 71 ++++ pkg/networking/route.go | 18 + pkg/networking/service.go | 34 ++ pkg/workloads/deployment.go | 42 ++ pkg/workloads/statefulset.go | 14 + 19 files changed, 1044 insertions(+), 7 deletions(-) create mode 100644 controllers/argocd/appcontroller/constants.go create mode 100644 controllers/argocd/redis/constants.go create mode 100644 controllers/argocd/redis/util.go create mode 100644 controllers/argocd/reposerver/constants.go create mode 100644 controllers/argocd/reposerver/deployment.go create mode 100644 controllers/argocd/reposerver/service.go create mode 100644 controllers/argocd/reposerver/servicemonitor.go create mode 100644 controllers/argocd/reposerver/tlssecret.go create mode 100644 controllers/argocd/reposerver/util.go diff --git a/common/envVars.go b/common/envVars.go index bffe28a0a..29721b233 100644 --- a/common/envVars.go +++ b/common/envVars.go @@ -43,4 +43,6 @@ const ( // ArgoCDClusterConfigNamespacesEnvVar is the environment variable that contains the list of namespaces allowed to host cluster config // instances ArgoCDClusterConfigNamespacesEnvVar = "ARGOCD_CLUSTER_CONFIG_NAMESPACES" + + ArgoCDExecTimeoutEnvVar = "ARGOCD_EXEC_TIMEOUT" ) diff --git a/common/keys.go b/common/keys.go index 7ece26085..ded1c20ec 100644 --- a/common/keys.go +++ b/common/keys.go @@ -129,6 +129,8 @@ const ( // ArgoCDDexSecretKey is used to reference Dex secret from Argo CD secret into Argo CD configmap ArgoCDDexSecretKey = "oidc.dex.clientSecret" + + ArgoCDRepoTLSCertChangedKey = "repo.tls.cert.changed" ) // openshift.io keys diff --git a/common/values.go b/common/values.go index 7ee54468e..0d7c36262 100644 --- a/common/values.go +++ b/common/values.go @@ -52,11 +52,18 @@ const ( TLSCerts = "tls-certs" + Server = "server" + CapabilityDropAll = "ALL" - VolumeMountPathTLS = "/app/config/tls" - VolumeMountPathRepoServerTLS = "/app/config/reposerver/tls" - WorkingDirApp = "/app" + VolumeMountPathTLS = "/app/config/tls" + VolumeMountPathRepoServerTLS = "/app/config/reposerver/tls" + WorkingDirApp = "/app" + VolumeMountPathRepoServerTLSRedis = "/app/config/reposerver/tls/redis" + VolumeMountPlugins = "plugins" + VolumeMountPathPlugins = "/home/argocd/cmp-server/plugins" + VolumeVarFiles = "var-files" + VolumeMountPathVarRunArgocd = "/var/run/argocd" ) // API group versions and resource kinds diff --git a/controllers/argocd/appcontroller/constants.go b/controllers/argocd/appcontroller/constants.go new file mode 100644 index 000000000..46bfdfdea --- /dev/null +++ b/controllers/argocd/appcontroller/constants.go @@ -0,0 +1,5 @@ +package appcontroller + +const ( + ArgoCDApplicationControllerComponent = "application-controller" +) diff --git a/controllers/argocd/argocdcommon/argohelper.go b/controllers/argocd/argocdcommon/argohelper.go index 3ecc12304..d25b6a9ff 100644 --- a/controllers/argocd/argocdcommon/argohelper.go +++ b/controllers/argocd/argocdcommon/argohelper.go @@ -1,11 +1,17 @@ package argocdcommon import ( + "fmt" "os" + "strings" "github.com/argoproj-labs/argocd-operator/api/v1alpha1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) func GetArgoContainerImage(cr *v1alpha1.ArgoCD) string { @@ -27,3 +33,42 @@ func GetArgoContainerImage(cr *v1alpha1.ArgoCD) string { return util.CombineImageTag(img, tag) } + +// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container +func GetArgoCmpServerInitCommand() []string { + cmd := make([]string, 0) + cmd = append(cmd, "cp") + cmd = append(cmd, "-n") + cmd = append(cmd, "/usr/local/bin/argocd") + cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") + return cmd +} + +// isOwnerOfInterest returns true if the given owner is one of the Argo CD services that +// may have been made the owner of the tls secret created by the OpenShift service CA, used +// to secure communication amongst the Argo CD components. +func IsOwnerOfInterest(owner metav1.OwnerReference) bool { + if owner.Kind != "Service" { + return false + } + if strings.HasSuffix(owner.Name, "-repo-server") { + return true + } + if strings.HasSuffix(owner.Name, "-redis") { + return true + } + return false +} + +// TriggerRollout will trigger a rollout of a Kubernetes resource specified as +// obj. It currently supports Deployment and StatefulSet resources. +func TriggerRollout(client cntrlClient.Client, obj interface{}, key string) error { + switch res := obj.(type) { + case *appsv1.Deployment: + return workloads.TriggerDeploymentRollout(client, res, key) + case *appsv1.StatefulSet: + return workloads.TriggerStatefulSetRollout(client, res, key) + default: + return fmt.Errorf("resource of unknown type %T, cannot trigger rollout", res) + } +} diff --git a/controllers/argocd/redis/constants.go b/controllers/argocd/redis/constants.go new file mode 100644 index 000000000..c466f13f9 --- /dev/null +++ b/controllers/argocd/redis/constants.go @@ -0,0 +1,5 @@ +package redis + +const ( + ArgoCDRedisControllerComponent = "redis" +) diff --git a/controllers/argocd/redis/redis.go b/controllers/argocd/redis/redis.go index 231e70699..676719186 100644 --- a/controllers/argocd/redis/redis.go +++ b/controllers/argocd/redis/redis.go @@ -4,6 +4,7 @@ import ( "github.com/argoproj-labs/argocd-operator/api/v1alpha1" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -15,6 +16,7 @@ type RedisReconciler struct { } func (rr *RedisReconciler) Reconcile() error { + rr.Logger = ctrl.Log.WithName(ArgoCDRedisControllerComponent).WithValues("instance", rr.Instance.Name, "instance-namespace", rr.Instance.Namespace) // controller logic goes here return nil diff --git a/controllers/argocd/redis/util.go b/controllers/argocd/redis/util.go new file mode 100644 index 000000000..c612c9cfe --- /dev/null +++ b/controllers/argocd/redis/util.go @@ -0,0 +1,62 @@ +package redis + +import ( + "context" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" +) + +func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, error) { + var tlsSecretObj corev1.Secret + tlsSecretName := types.NamespacedName{Namespace: instanceNamespace, Name: common.ArgoCDRedisServerTLSSecretName} + err := client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) + if err != nil { + if !errors.IsNotFound(err) { + // Error reading the secret + return false, err + } + return false, nil + } + + secretOwnerRefs := tlsSecretObj.GetOwnerReferences() + if len(secretOwnerRefs) > 0 { + // OpenShift service CA makes the owner reference for the TLS secret to the + // service, which in turn is owned by the controller. This method performs + // a lookup of the controller through the intermediate owning service. + for _, secretOwner := range secretOwnerRefs { + if argocdcommon.IsOwnerOfInterest(secretOwner) { + key := cntrlClient.ObjectKey{Name: secretOwner.Name, Namespace: tlsSecretObj.GetNamespace()} + svc := &corev1.Service{} + + // Get the owning object of the secret + err := client.Get(context.TODO(), key, svc) + if err != nil { + // log.Error(err, fmt.Sprintf("could not get owner of secret %s", tlsSecretObj.GetName())) + return false, err + } + + // If there's an object of kind ArgoCD in the owner's list, + // this will be our reconciled object. + serviceOwnerRefs := svc.GetOwnerReferences() + for _, serviceOwner := range serviceOwnerRefs { + if serviceOwner.Kind == "ArgoCD" { + return true, nil + } + } + } + } + } else { + // For secrets without owner (i.e. manually created), we apply some + // heuristics. This may not be as accurate (e.g. if the user made a + // typo in the resource's name), but should be good enough for now. + if _, ok := tlsSecretObj.Annotations[common.ArgoCDArgoprojKeyName]; ok { + return true, nil + } + } + return false, nil +} diff --git a/controllers/argocd/reposerver/constants.go b/controllers/argocd/reposerver/constants.go new file mode 100644 index 000000000..179da6a69 --- /dev/null +++ b/controllers/argocd/reposerver/constants.go @@ -0,0 +1,11 @@ +package reposerver + +// Values +const ( + ArgoCDRepoServerControllerComponent = "repo-server" + ArgoCDRepoServerController = "argocd-repo-server" + RepoServerMetrics = "repo-server-metrics" + ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" + // RepoServerSecretName = "argocd-repo-server-secret" + // RepoServerConfigMapName = "argocd-repo-server-cm" +) diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go new file mode 100644 index 000000000..3b62d55bc --- /dev/null +++ b/controllers/argocd/reposerver/deployment.go @@ -0,0 +1,387 @@ +package reposerver + +import ( + "fmt" + "time" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/redis" + "github.com/argoproj-labs/argocd-operator/pkg/cluster" + "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *appsv1.Deployment { + desiredDeployment := &appsv1.Deployment{} + + repoServerEnv := rsr.Instance.Spec.Repo.Env + repoServerEnv = util.EnvMerge(repoServerEnv, util.ProxyEnvVars(), false) + + if rsr.Instance.Spec.Repo.ExecTimeout != nil { + repoServerEnv = util.EnvMerge(repoServerEnv, []corev1.EnvVar{{Name: common.ArgoCDExecTimeoutEnvVar, Value: fmt.Sprintf("%ds", *rsr.Instance.Spec.Repo.ExecTimeout)}}, true) + } + + automountToken := false + if rsr.Instance.Spec.Repo.MountSAToken { + automountToken = rsr.Instance.Spec.Repo.MountSAToken + } + + objMeta := metav1.ObjectMeta{ + Name: resourceName, + Namespace: rsr.Instance.Namespace, + Labels: resourceLabels, + } + podSpec := corev1.PodSpec{ + Volumes: rsr.getRepoServerPodVolumes(), + InitContainers: rsr.getRepoSeverInitContainers(), + Containers: rsr.getRepoServerContainers(useTLSForRedis), + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: util.BoolPtr(true), + }, + AutomountServiceAccountToken: &automountToken, + } + + deploymentSpec := appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: podSpec, + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + common.AppK8sKeyName: resourceName, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.AppK8sKeyName: resourceName, + }, + }, + Replicas: rsr.GetArgoCDRepoServerReplicas(), + } + + desiredDeployment.ObjectMeta = objMeta + desiredDeployment.Spec = deploymentSpec + return desiredDeployment +} + +func (rsr *RepoServerReconciler) getDeploymentRequest(dep appsv1.Deployment) workloads.DeploymentRequest { + deploymentReq := workloads.DeploymentRequest{ + ObjectMeta: dep.ObjectMeta, + Spec: dep.Spec, + Client: rsr.Client, + Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, + } + + return deploymentReq +} + +func (rsr *RepoServerReconciler) reconcileDeployment() error { + + rsr.Logger.Info("reconciling deployment") + + useTLSForRedis, err := redis.ShouldUseTLS(rsr.Client, rsr.Instance.Namespace) + if err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to determine if TLS should be used for Redis") + return err + } + + desiredDeployment := rsr.getDesiredDeployment(useTLSForRedis) + deploymentRequest := rsr.getDeploymentRequest(*desiredDeployment) + + desiredDeployment, err = workloads.RequestDeployment(deploymentRequest) + if err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + rsr.Logger.V(1).Info("reconcileDeployment: one or more mutations could not be applied") + return err + } + + namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to retrieve namespace", "name", rsr.Instance.Namespace) + return err + } + if namespace.DeletionTimestamp != nil { + if err := rsr.DeleteDeployment(desiredDeployment.Name, desiredDeployment.Namespace); err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to delete deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + } + return err + } + + existingDeployment, err := workloads.GetDeployment(desiredDeployment.Name, desiredDeployment.Namespace, rsr.Client) + if err != nil { + if !errors.IsNotFound(err) { + rsr.Logger.Error(err, "reconcileDeployment: failed to retrieve deployment", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + return err + } + + if err = controllerutil.SetControllerReference(rsr.Instance, desiredDeployment, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to set owner reference for deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + } + + if err = workloads.CreateDeployment(desiredDeployment, rsr.Client); err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to create deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + return err + } + rsr.Logger.V(0).Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + return nil + } + deploymentChanged := false + + fieldsToCompare := []struct { + existing, desired interface{} + extraAction func() + }{ + {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, + func() { + existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) + }, + }, + {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, + {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, + {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, + {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, + {&existingDeployment.Spec.Template.Spec.NodeSelector, &desiredDeployment.Spec.Template.Spec.NodeSelector, nil}, + {&existingDeployment.Spec.Template.Spec.Tolerations, &desiredDeployment.Spec.Template.Spec.Tolerations, nil}, + {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, + {&existingDeployment.Spec.Template.Labels, &desiredDeployment.Spec.Template.Labels, nil}, + {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, + {&existingDeployment.Spec.Selector, &desiredDeployment.Spec.Selector, nil}, + {&existingDeployment.Labels, &desiredDeployment.Labels, nil}, + } + + for _, field := range fieldsToCompare { + argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deploymentChanged) + } + + if deploymentChanged { + + if err = workloads.UpdateDeployment(existingDeployment, rsr.Client); err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to update deployment", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + return err + } + } + + rsr.Logger.V(0).Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + return nil +} + +func (rsr *RepoServerReconciler) DeleteDeployment(name, namespace string) error { + if err := workloads.DeleteDeployment(name, namespace, rsr.Client); err != nil { + rsr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) + return err + } + rsr.Logger.V(0).Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) + return nil +} + +func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container { + initContainers := []corev1.Container{{ + Name: "copyutil", + Image: argocdcommon.GetArgoContainerImage(rsr.Instance), + Command: argocdcommon.GetArgoCmpServerInitCommand(), + ImagePullPolicy: corev1.PullAlways, + Resources: rsr.getArgoRepoResources(), + Env: util.ProxyEnvVars(), + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: util.BoolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + common.CapabilityDropAll, + }, + }, + RunAsNonRoot: util.BoolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: common.VolumeVarFiles, + MountPath: common.VolumeMountPathVarRunArgocd, + }, + }, + }} + if (rsr.Instance.Spec.Repo.InitContainers != nil) && len(rsr.Instance.Spec.Repo.InitContainers) > 0 { + initContainers = append(initContainers, rsr.Instance.Spec.Repo.InitContainers...) + } + return initContainers +} + +func (rsr *RepoServerReconciler) getRepoServerContainers(useTLSForRedis bool) []corev1.Container { + repoServerEnv := rsr.Instance.Spec.Repo.Env + repoServerEnv = util.EnvMerge(repoServerEnv, util.ProxyEnvVars(), false) + + containers := []corev1.Container{{ + Command: rsr.GetArgoRepoServerCommand(useTLSForRedis), + Image: argocdcommon.GetArgoContainerImage(rsr.Instance), + ImagePullPolicy: corev1.PullAlways, + Name: ArgoCDRepoServerController, + Env: repoServerEnv, + Resources: rsr.GetRepoServerResources(), + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + Ports: []corev1.ContainerPort{ + { + ContainerPort: common.ArgoCDDefaultRepoServerPort, + Name: common.Server, + }, { + ContainerPort: common.ArgoCDDefaultRepoMetricsPort, + Name: common.ArgoCDMetrics, + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: util.BoolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + common.CapabilityDropAll, + }, + }, + RunAsNonRoot: util.BoolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: common.SSHKnownHosts, + MountPath: common.VolumeMountPathSSH, + }, + { + Name: common.TLSCerts, + MountPath: common.VolumeMountPathTLS, + }, + { + Name: common.GPGKeys, + MountPath: common.VolumeMountPathGPG, + }, + { + Name: common.GPGKeyRing, + MountPath: common.VolumeMountPathGPGKeyring, + }, + { + Name: common.VolumeTmp, + MountPath: common.VolumeMountPathTmp, + }, + { + Name: common.ArgoCDRepoServerTLSSecretName, + MountPath: common.VolumeMountPathRepoServerTLS, + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + MountPath: common.VolumeMountPathRepoServerTLSRedis, + }, + { + Name: common.VolumeMountPlugins, + MountPath: common.VolumeMountPathPlugins, + }, + }, + }} + if rsr.Instance.Spec.Repo.VolumeMounts != nil { + containers[0].VolumeMounts = append(containers[0].VolumeMounts, rsr.Instance.Spec.Repo.VolumeMounts...) + } + + if rsr.Instance.Spec.Repo.SidecarContainers != nil { + containers = append(containers, rsr.Instance.Spec.Repo.SidecarContainers...) + } + + return containers +} + +func (rsr *RepoServerReconciler) getRepoServerPodVolumes() []corev1.Volume { + volumes := []corev1.Volume{ + { + Name: common.SSHKnownHosts, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDKnownHostsConfigMapName, + }, + }, + }, + }, + { + Name: common.TLSCerts, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDTLSCertsConfigMapName, + }, + }, + }, + }, + { + Name: common.GPGKeys, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDGPGKeysConfigMapName, + }, + }, + }, + }, + { + Name: common.GPGKeyRing, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: common.VolumeTmp, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: common.ArgoCDRepoServerTLS, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRepoServerTLSSecretName, + Optional: util.BoolPtr(true), + }, + }, + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRedisServerTLSSecretName, + Optional: util.BoolPtr(true), + }, + }, + }, + { + Name: common.VolumeVarFiles, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: common.VolumeMountPlugins, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + } + if rsr.Instance.Spec.Repo.Volumes != nil && len(rsr.Instance.Spec.Repo.Volumes) > 0 { + volumes = append(volumes, rsr.Instance.Spec.Repo.Volumes...) + } + return volumes +} diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 41cc01a50..4d2e997e9 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -1,21 +1,68 @@ package reposerver import ( - "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) type RepoServerReconciler struct { - Client *client.Client + Client client.Client Scheme *runtime.Scheme - Instance *v1alpha1.ArgoCD + Instance *v1beta1.ArgoCD Logger logr.Logger } +var ( + resourceName string + resourceLabels map[string]string +) + func (rsr *RepoServerReconciler) Reconcile() error { + rsr.Logger = ctrl.Log.WithName(ArgoCDRepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) + resourceName = util.GenerateResourceName(rsr.Instance.Name, ArgoCDRepoServerControllerComponent) + resourceLabels = common.DefaultLabels(resourceName, rsr.Instance.Name, ArgoCDRepoServerControllerComponent) + + if err := rsr.reconcileService(); err != nil { + rsr.Logger.Info("reconciling repo server service") + return err + } + + if err := rsr.reconcileTLSSecret(); err != nil { + rsr.Logger.Info("reconciling repo server secret") + return err + } + + if err := rsr.reconcileDeployment(); err != nil { + rsr.Logger.Info("reconciling repo server deployment") + return err + } - // controller logic goes here return nil } + +func (rsr *RepoServerReconciler) DeleteResources() error { + + var deletionError error = nil + + if err := rsr.DeleteDeployment(resourceName, rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "DeleteResources: failed to delete deployment") + deletionError = err + } + + if err := rsr.DeleteTLSSecret(rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "DeleteResources: failed to delete secret") + deletionError = err + } + + if err := rsr.DeleteService(resourceName, rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "DeleteResources: failed to delete service") + deletionError = err + } + + return deletionError +} diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go new file mode 100644 index 000000000..997151807 --- /dev/null +++ b/controllers/argocd/reposerver/service.go @@ -0,0 +1,107 @@ +package reposerver + +import ( + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/cluster" + "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/pkg/networking" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func (rsr *RepoServerReconciler) reconcileService() error { + + rsr.Logger.Info("reconciling service") + + serviceRequest := networking.ServiceRequest{ + ObjectMeta: metav1.ObjectMeta{ + Name: resourceName, + Namespace: rsr.Instance.Namespace, + Labels: resourceLabels, + Annotations: rsr.Instance.Annotations, + }, + Spec: GetServiceSpec(), + Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, + Client: rsr.Client, + } + + desiredService, err := networking.RequestService(serviceRequest) + + namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "reconcileService: failed to retrieve namespace", "name", rsr.Instance.Namespace) + return err + } + if namespace.DeletionTimestamp != nil { + if err := rsr.DeleteService(desiredService.Name, desiredService.Namespace); err != nil { + rsr.Logger.Error(err, "reconcileService: failed to delete service", "name", desiredService.Name, "namespace", desiredService.Namespace) + } + return err + } + + existingService, err := networking.GetService(desiredService.Name, desiredService.Namespace, rsr.Client) + if err != nil { + if !errors.IsNotFound(err) { + rsr.Logger.Error(err, "reconcileService: failed to retrieve service", "name", existingService.Name, "namespace", existingService.Namespace) + return err + } + + if err = controllerutil.SetControllerReference(rsr.Instance, desiredService, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desiredService.Name, "namespace", desiredService.Namespace) + } + + networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Spec.Repo.WantsAutoTLS(), rsr.Logger) + + if err = networking.CreateService(desiredService, rsr.Client); err != nil { + rsr.Logger.Error(err, "reconcileService: failed to create service", "name", desiredService.Name, "namespace", desiredService.Namespace) + return err + } + rsr.Logger.V(0).Info("reconcileService: service created", "name", desiredService.Name, "namespace", desiredService.Namespace) + return nil + } + + if networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Spec.Repo.WantsAutoTLS(), rsr.Logger) { + if err = networking.UpdateService(existingService, rsr.Client); err != nil { + rsr.Logger.Error(err, "reconcileService: failed to update service", "name", existingService.Name, "namespace", existingService.Namespace) + return err + } + } + rsr.Logger.V(0).Info("reconcileService: service updated", "name", existingService.Name, "namespace", existingService.Namespace) + + return nil +} + +func (rsr *RepoServerReconciler) DeleteService(name, namespace string) error { + if err := networking.DeleteService(name, namespace, rsr.Client); err != nil { + rsr.Logger.Error(err, "DeleteService: failed to delete service", "name", name, "namespace", namespace) + return err + } + rsr.Logger.V(0).Info("DeleteService: service deleted", "name", name, "namespace", namespace) + return nil +} + +func GetServiceSpec() corev1.ServiceSpec { + return corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: common.Server, + Port: common.ArgoCDDefaultRepoServerPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + { + Name: common.ArgoCDMetrics, + Port: common.ArgoCDDefaultRepoMetricsPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoMetricsPort), + }, + }, + Selector: map[string]string{ + common.AppK8sKeyName: resourceName, + }, + } +} diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go new file mode 100644 index 000000000..00d12d7d8 --- /dev/null +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -0,0 +1,69 @@ +package reposerver + +import ( + "github.com/argoproj-labs/argocd-operator/pkg/cluster" + "github.com/argoproj-labs/argocd-operator/pkg/monitoring" + "github.com/argoproj-labs/argocd-operator/pkg/util" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { + + rsr.Logger.Info("reconciling serviceMonitor") + + serviceMonitorRequest := monitoring.ServiceMonitorRequest{ + ObjectMeta: metav1.ObjectMeta{ + Name: util.GenerateResourceName(rsr.Instance.Name, RepoServerMetrics), + Namespace: rsr.Instance.Namespace, + Labels: resourceLabels, + Annotations: rsr.Instance.Annotations, + }, + } + + desiredServiceMonitor, err := monitoring.RequestServiceMonitor(serviceMonitorRequest) + + namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to retrieve namespace", "name", rsr.Instance.Namespace) + return err + } + if namespace.DeletionTimestamp != nil { + if err := rsr.DeleteServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace); err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to delete serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + } + return err + } + + existingServiceMonitor, err := monitoring.GetServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace, rsr.Client) + if err != nil { + if !errors.IsNotFound(err) { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to retrieve serviceMonitor", "name", existingServiceMonitor.Name, "namespace", existingServiceMonitor.Namespace) + return err + } + + if err = controllerutil.SetControllerReference(rsr.Instance, desiredServiceMonitor, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to set owner reference for serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + } + + if err = monitoring.CreateServiceMonitor(desiredServiceMonitor, rsr.Client); err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to create serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + return err + } + rsr.Logger.V(0).Info("reconcileServiceMonitor: serviceMonitor created", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + return nil + } + + return nil +} + +func (rsr *RepoServerReconciler) DeleteServiceMonitor(name, namespace string) error { + if err := monitoring.DeleteServiceMonitor(name, namespace, rsr.Client); err != nil { + rsr.Logger.Error(err, "DeleteServiceMonitor: failed to delete serviceMonitor", "name", name, "namespace", namespace) + return err + } + rsr.Logger.V(0).Info("DeleteServiceMonitor: serviceMonitor deleted", "name", name, "namespace", namespace) + return nil +} diff --git a/controllers/argocd/reposerver/tlssecret.go b/controllers/argocd/reposerver/tlssecret.go new file mode 100644 index 000000000..42d01eff2 --- /dev/null +++ b/controllers/argocd/reposerver/tlssecret.go @@ -0,0 +1,107 @@ +package reposerver + +import ( + "crypto/sha256" + "fmt" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/appcontroller" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/cluster" + "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (rsr *RepoServerReconciler) reconcileTLSSecret() error { + var sha256sum string + rsr.Logger.Info("reconciling TLS secrets") + + secretRequest := workloads.SecretRequest{ + ObjectMeta: metav1.ObjectMeta{ + Name: ArgoCDRepoServerTLSSecretName, + Namespace: rsr.Instance.Namespace, + Labels: resourceLabels, + }, + + Client: rsr.Client, + Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, + } + + desiredSecret, err := workloads.RequestSecret(secretRequest) + if err != nil { + rsr.Logger.Error(err, "reconcileSecret: failed to request secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + rsr.Logger.V(1).Info("reconcileSecret: one or more mutations could not be applied") + return err + } + + namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "reconcileSecret: failed to retrieve namespace", "name", rsr.Instance.Namespace) + return err + } + if namespace.DeletionTimestamp != nil { + if err := rsr.DeleteTLSSecret(desiredSecret.Namespace); err != nil { + rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + } + return err + } + + existingSecret, err := workloads.GetSecret(desiredSecret.Name, desiredSecret.Namespace, rsr.Client) + if err != nil { + if !errors.IsNotFound(err) { + rsr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", existingSecret.Name, "namespace", existingSecret.Namespace) + return err + } + } else if existingSecret.Type != corev1.SecretTypeTLS { + return nil + } else { + crt, crtOk := existingSecret.Data[corev1.TLSCertKey] + key, keyOk := existingSecret.Data[corev1.TLSPrivateKeyKey] + if crtOk && keyOk { + var sumBytes []byte + sumBytes = append(sumBytes, crt...) + sumBytes = append(sumBytes, key...) + sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) + } + } + + if rsr.Instance.Status.RepoTLSChecksum != sha256sum { + rsr.Instance.Status.RepoTLSChecksum = sha256sum + err = workloads.UpdateSecret(desiredSecret, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "reconcileSecret: failed to update secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + return err + } + + // Trigger rollout of API components + components := []string{common.Server, ArgoCDRepoServerControllerComponent, appcontroller.ArgoCDApplicationControllerComponent} + for _, component := range components { + depl, err := workloads.CreateDeploymentWithSuffix(component, component, rsr.Instance) + if err != nil { + return err + } + err = argocdcommon.TriggerRollout(rsr.Client, depl, common.ArgoCDRepoTLSCertChangedKey) + if err != nil { + return err + } + } + + rsr.Logger.V(0).Info("reconcileSecret: TLS secret updated", "name", ArgoCDRepoServerTLSSecretName, "namespace", desiredSecret.Namespace) + return nil + } + + return nil +} + +func (rsr *RepoServerReconciler) DeleteTLSSecret(namespace string) error { + if err := workloads.DeleteSecret(ArgoCDRepoServerTLSSecretName, namespace, rsr.Client); err != nil { + rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", ArgoCDRepoServerTLSSecretName, "namespace", namespace) + return err + } + rsr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", ArgoCDRepoServerTLSSecretName, "namespace", namespace) + return nil +} diff --git a/controllers/argocd/reposerver/util.go b/controllers/argocd/reposerver/util.go new file mode 100644 index 000000000..28d90d737 --- /dev/null +++ b/controllers/argocd/reposerver/util.go @@ -0,0 +1,71 @@ +package reposerver + +import ( + "context" + "fmt" + + "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// GetRepoServerResources will return the ResourceRequirements for the Argo CD Repo server container. +func (rsr *RepoServerReconciler) GetRepoServerResources() corev1.ResourceRequirements { + resources := corev1.ResourceRequirements{} + + // Allow override of resource requirements from CR + if rsr.Instance.Spec.Repo.Resources != nil { + resources = *rsr.Instance.Spec.Repo.Resources + } + + return resources +} + +// GetArgoRepoServerCommand will return the command for the ArgoCD Repo component. +func (rsr *RepoServerReconciler) GetArgoRepoServerCommand(useTLSForRedis bool) []string { + cmd := make([]string, 0) + + cmd = append(cmd, "uid_entrypoint.sh") + cmd = append(cmd, "argocd-repo-server") + + cmd = append(cmd, "--redis") + cmd = append(cmd, getRedisServerAddress(cr)) + + if useTLSForRedis { + cmd = append(cmd, "--redis-use-tls") + if isRedisTLSVerificationDisabled(cr) { + cmd = append(cmd, "--redis-insecure-skip-tls-verify") + } else { + cmd = append(cmd, "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt") + } + } + + cmd = append(cmd, "--loglevel") + cmd = append(cmd, getLogLevel(cr.Spec.Repo.LogLevel)) + + cmd = append(cmd, "--logformat") + cmd = append(cmd, getLogFormat(cr.Spec.Repo.LogFormat)) + + // *** NOTE *** + // Do Not add any new default command line arguments below this. + extraArgs := cr.Spec.Repo.ExtraRepoCommandArgs + err := isMergable(extraArgs, cmd) + if err != nil { + return cmd + } + + cmd = append(cmd, extraArgs...) + return cmd +} + +func (rsr *RepoServerReconciler) GetArgoCDRepoServerReplicas() *int32 { + if rsr.Instance.Spec.Repo.Replicas != nil && *rsr.Instance.Spec.Repo.Replicas >= 0 { + return rsr.Instance.Spec.Repo.Replicas + } + + return nil +} diff --git a/pkg/networking/route.go b/pkg/networking/route.go index 83098679e..0b8a58ae7 100644 --- a/pkg/networking/route.go +++ b/pkg/networking/route.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/pkg/util" routev1 "github.com/openshift/api/route/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,6 +23,23 @@ type RouteRequest struct { Client cntrlClient.Client } +var routeAPIFound = false + +// IsRouteAPIAvailable returns true if the Route API is present. +func IsRouteAPIAvailable() bool { + return routeAPIFound +} + +// verifyRouteAPI will verify that the Route API is present. +func VerifyRouteAPI() error { + found, err := util.VerifyAPI(routev1.GroupName, routev1.GroupVersion.Version) + if err != nil { + return err + } + routeAPIFound = found + return nil +} + // newRoute returns a new Route instance for the given ArgoCD. func newRoute(objectMeta metav1.ObjectMeta, spec routev1.RouteSpec) *routev1.Route { return &routev1.Route{ diff --git a/pkg/networking/service.go b/pkg/networking/service.go index e7f2af2ca..2ba5d53cf 100644 --- a/pkg/networking/service.go +++ b/pkg/networking/service.go @@ -4,7 +4,9 @@ import ( "context" "fmt" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -100,3 +102,35 @@ func RequestService(request ServiceRequest) (*corev1.Service, error) { return service, nil } + +func EnsureAutoTLSAnnotation(svc *corev1.Service, secretName string, enabled bool, log logr.Logger) bool { + var autoTLSAnnotationName, autoTLSAnnotationValue string + + // We currently only support OpenShift for automatic TLS + if IsRouteAPIAvailable() { + autoTLSAnnotationName = common.ServiceBetaOpenshiftKeyCertSecret + if svc.Annotations == nil { + svc.Annotations = make(map[string]string) + } + autoTLSAnnotationValue = secretName + } + + if autoTLSAnnotationName != "" { + val, ok := svc.Annotations[autoTLSAnnotationName] + if enabled { + if !ok || val != secretName { + log.Info(fmt.Sprintf("requesting AutoTLS on service %s", svc.ObjectMeta.Name)) + svc.Annotations[autoTLSAnnotationName] = autoTLSAnnotationValue + return true + } + } else { + if ok { + log.Info(fmt.Sprintf("removing AutoTLS from service %s", svc.ObjectMeta.Name)) + delete(svc.Annotations, autoTLSAnnotationName) + return true + } + } + } + + return false +} diff --git a/pkg/workloads/deployment.go b/pkg/workloads/deployment.go index 466f253c0..a9c337008 100644 --- a/pkg/workloads/deployment.go +++ b/pkg/workloads/deployment.go @@ -3,8 +3,12 @@ package workloads import ( "context" "fmt" + "time" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + util "github.com/argoproj-labs/argocd-operator/pkg/util" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -101,3 +105,41 @@ func RequestDeployment(request DeploymentRequest) (*appsv1.Deployment, error) { return deployment, nil } + +func CreateDeploymentWithSuffix(suffix string, component string, cr *argoproj.ArgoCD) (*appsv1.Deployment, error) { + lbls := cr.Labels + lbls[common.AppK8sKeyComponent] = component + deploymentRequest := DeploymentRequest{ + ObjectMeta: metav1.ObjectMeta{ + Name: util.NameWithSuffix(cr.Name, suffix), + Namespace: cr.Namespace, + Labels: lbls, + }, + } + + deployment, err := RequestDeployment(deploymentRequest) + if err != nil { + return nil, err + } + + return deployment, nil +} + +// TriggerDeploymentRollout will update the label with the given key to trigger a new rollout of the Deployment. +func TriggerDeploymentRollout(client cntrlClient.Client, deployment *appsv1.Deployment, key string) error { + currentDeployment, err := GetDeployment(deployment.Name, deployment.Namespace, client) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + return nil + } + + currentDeployment.Spec.Template.ObjectMeta.Labels[key] = NowNano() + return UpdateDeployment(currentDeployment, client) +} + +// nowNano returns a string with the current UTC time as epoch in nanoseconds +func NowNano() string { + return fmt.Sprintf("%d", time.Now().UTC().UnixNano()) +} diff --git a/pkg/workloads/statefulset.go b/pkg/workloads/statefulset.go index 6ccad15bd..613d39ff7 100644 --- a/pkg/workloads/statefulset.go +++ b/pkg/workloads/statefulset.go @@ -100,3 +100,17 @@ func RequestStatefulSet(request StatefulSetRequest) (*appsv1.StatefulSet, error) return StatefulSet, nil } + +// TriggerStatefulSetRollout will update the label with the given key to trigger a new rollout of the StatefulSet. +func TriggerStatefulSetRollout(client cntrlClient.Client, sts *appsv1.StatefulSet, key string) error { + currentStatefulSet, err := GetStatefulSet(sts.Name, sts.Namespace, client) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + return nil + } + + currentStatefulSet.Spec.Template.ObjectMeta.Labels[key] = NowNano() + return UpdateStatefulSet(currentStatefulSet, client) +} From 070d37b1d57d819a7a2a51e05b57b22ad3bb9fb7 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Tue, 3 Oct 2023 11:27:05 -0400 Subject: [PATCH 22/94] Resolved some compiler errors Signed-off-by: Yi Cai --- controllers/argocd/argocd_controller.go | 2 +- .../argocd/notifications/rolebinding.go | 4 +- controllers/argocd/redis/constants.go | 10 +++- controllers/argocd/redis/redis.go | 2 +- controllers/argocd/reposerver/constants.go | 19 +++++-- controllers/argocd/reposerver/deployment.go | 6 +-- controllers/argocd/reposerver/reposerver.go | 6 +-- controllers/argocd/reposerver/tlssecret.go | 12 ++--- controllers/argocd/reposerver/util.go | 52 +++++++++++-------- pkg/util/string.go | 11 ++++ 10 files changed, 80 insertions(+), 44 deletions(-) diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 56c3cebb9..2976095dd 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -303,7 +303,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { } r.ReposerverController = &reposerver.RepoServerReconciler{ - Client: &r.Client, + Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, } diff --git a/controllers/argocd/notifications/rolebinding.go b/controllers/argocd/notifications/rolebinding.go index a2ebdd6f8..a7d1075f7 100644 --- a/controllers/argocd/notifications/rolebinding.go +++ b/controllers/argocd/notifications/rolebinding.go @@ -14,12 +14,12 @@ import ( func (nr *NotificationsReconciler) reconcileRoleBinding() error { - nr.Logger.Info("reconciling roleBindings") + nr.Logger.Info("reconciling roleBinding") sa, err := permissions.GetServiceAccount(resourceName, nr.Instance.Namespace, nr.Client) if err != nil { - nr.Logger.Error(err, "reconsileRoleBinding: failed to get serviceaccount", "name", resourceName, "namespace", nr.Instance.Namespace) + nr.Logger.Error(err, "reconcileRoleBinding: failed to get serviceaccount", "name", resourceName, "namespace", nr.Instance.Namespace) return err } diff --git a/controllers/argocd/redis/constants.go b/controllers/argocd/redis/constants.go index c466f13f9..c8ec901a0 100644 --- a/controllers/argocd/redis/constants.go +++ b/controllers/argocd/redis/constants.go @@ -1,5 +1,13 @@ package redis const ( - ArgoCDRedisControllerComponent = "redis" + // Values + RedisControllerComponent = "redis" + RedisHAProxyServiceName = "redis-ha-haproxy" + + // Commands + Redis = "--redis" + RedisUseTLS = "--redis-use-tls" + RedisInsecureSkipTLSVerify = "--redis-insecure-skip-tls-verify" + RedisCACertificate = "--redis-ca-certificate" ) diff --git a/controllers/argocd/redis/redis.go b/controllers/argocd/redis/redis.go index a181e48f7..a42a46554 100644 --- a/controllers/argocd/redis/redis.go +++ b/controllers/argocd/redis/redis.go @@ -16,7 +16,7 @@ type RedisReconciler struct { } func (rr *RedisReconciler) Reconcile() error { - rr.Logger = ctrl.Log.WithName(ArgoCDRedisControllerComponent).WithValues("instance", rr.Instance.Name, "instance-namespace", rr.Instance.Namespace) + rr.Logger = ctrl.Log.WithName(RedisControllerComponent).WithValues("instance", rr.Instance.Name, "instance-namespace", rr.Instance.Namespace) // controller logic goes here return nil diff --git a/controllers/argocd/reposerver/constants.go b/controllers/argocd/reposerver/constants.go index 179da6a69..a7ff74b7f 100644 --- a/controllers/argocd/reposerver/constants.go +++ b/controllers/argocd/reposerver/constants.go @@ -1,11 +1,20 @@ package reposerver -// Values const ( - ArgoCDRepoServerControllerComponent = "repo-server" - ArgoCDRepoServerController = "argocd-repo-server" - RepoServerMetrics = "repo-server-metrics" - ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" + // Values + RepoServerControllerComponent = "repo-server" + RepoServerController = "argocd-repo-server" + RepoServerMetrics = "repo-server-metrics" + RepoServerTLSSecretName = "argocd-repo-server-tls" + RedisHAProxyServiceName = "redis-ha-haproxy" + CopyUtil = "copyutil" // RepoServerSecretName = "argocd-repo-server-secret" // RepoServerConfigMapName = "argocd-repo-server-cm" + + // Commands + UidEntryPointSh = "uid_entrypoint.sh" + LogLevel = "--loglevel" + LogFormat = "--logformat" + ArgoCDRepoServer = "--argocd-repo-server" + RepoServerTLSRedisCertPath = "/app/config/reposerver/tls/redis/tls.crt" ) diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 3b62d55bc..2ef21eab0 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -184,11 +184,11 @@ func (rsr *RepoServerReconciler) DeleteDeployment(name, namespace string) error func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container { initContainers := []corev1.Container{{ - Name: "copyutil", + Name: CopyUtil, Image: argocdcommon.GetArgoContainerImage(rsr.Instance), Command: argocdcommon.GetArgoCmpServerInitCommand(), ImagePullPolicy: corev1.PullAlways, - Resources: rsr.getArgoRepoResources(), + Resources: rsr.GetRepoServerResources(), Env: util.ProxyEnvVars(), SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: util.BoolPtr(false), @@ -220,7 +220,7 @@ func (rsr *RepoServerReconciler) getRepoServerContainers(useTLSForRedis bool) [] Command: rsr.GetArgoRepoServerCommand(useTLSForRedis), Image: argocdcommon.GetArgoContainerImage(rsr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: ArgoCDRepoServerController, + Name: RepoServerController, Env: repoServerEnv, Resources: rsr.GetRepoServerResources(), LivenessProbe: &corev1.Probe{ diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index f14082829..6f314d91b 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -23,9 +23,9 @@ var ( ) func (rsr *RepoServerReconciler) Reconcile() error { - rsr.Logger = ctrl.Log.WithName(ArgoCDRepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) - resourceName = util.GenerateResourceName(rsr.Instance.Name, ArgoCDRepoServerControllerComponent) - resourceLabels = common.DefaultLabels(resourceName, rsr.Instance.Name, ArgoCDRepoServerControllerComponent) + rsr.Logger = ctrl.Log.WithName(RepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) + resourceName = util.GenerateResourceName(rsr.Instance.Name, RepoServerControllerComponent) + resourceLabels = common.DefaultLabels(resourceName, rsr.Instance.Name, RepoServerControllerComponent) if err := rsr.reconcileService(); err != nil { rsr.Logger.Info("reconciling repo server service") diff --git a/controllers/argocd/reposerver/tlssecret.go b/controllers/argocd/reposerver/tlssecret.go index 42d01eff2..a40dbbb99 100644 --- a/controllers/argocd/reposerver/tlssecret.go +++ b/controllers/argocd/reposerver/tlssecret.go @@ -22,7 +22,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { secretRequest := workloads.SecretRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: ArgoCDRepoServerTLSSecretName, + Name: RepoServerTLSSecretName, Namespace: rsr.Instance.Namespace, Labels: resourceLabels, }, @@ -78,7 +78,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } // Trigger rollout of API components - components := []string{common.Server, ArgoCDRepoServerControllerComponent, appcontroller.ArgoCDApplicationControllerComponent} + components := []string{common.Server, RepoServerControllerComponent, appcontroller.ArgoCDApplicationControllerComponent} for _, component := range components { depl, err := workloads.CreateDeploymentWithSuffix(component, component, rsr.Instance) if err != nil { @@ -90,7 +90,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } } - rsr.Logger.V(0).Info("reconcileSecret: TLS secret updated", "name", ArgoCDRepoServerTLSSecretName, "namespace", desiredSecret.Namespace) + rsr.Logger.V(0).Info("reconcileSecret: TLS secret updated", "name", RepoServerTLSSecretName, "namespace", desiredSecret.Namespace) return nil } @@ -98,10 +98,10 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } func (rsr *RepoServerReconciler) DeleteTLSSecret(namespace string) error { - if err := workloads.DeleteSecret(ArgoCDRepoServerTLSSecretName, namespace, rsr.Client); err != nil { - rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", ArgoCDRepoServerTLSSecretName, "namespace", namespace) + if err := workloads.DeleteSecret(RepoServerTLSSecretName, namespace, rsr.Client); err != nil { + rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", RepoServerTLSSecretName, "namespace", namespace) return err } - rsr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", ArgoCDRepoServerTLSSecretName, "namespace", namespace) + rsr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", RepoServerTLSSecretName, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/util.go b/controllers/argocd/reposerver/util.go index 28d90d737..9333c5177 100644 --- a/controllers/argocd/reposerver/util.go +++ b/controllers/argocd/reposerver/util.go @@ -1,16 +1,11 @@ package reposerver import ( - "context" - "fmt" - - "github.com/argoproj-labs/argocd-operator/api/v1beta1" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/redis" + "github.com/argoproj-labs/argocd-operator/pkg/util" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" ) // GetRepoServerResources will return the ResourceRequirements for the Argo CD Repo server container. @@ -29,31 +24,31 @@ func (rsr *RepoServerReconciler) GetRepoServerResources() corev1.ResourceRequire func (rsr *RepoServerReconciler) GetArgoRepoServerCommand(useTLSForRedis bool) []string { cmd := make([]string, 0) - cmd = append(cmd, "uid_entrypoint.sh") - cmd = append(cmd, "argocd-repo-server") + cmd = append(cmd, UidEntryPointSh) + cmd = append(cmd, RepoServerController) - cmd = append(cmd, "--redis") - cmd = append(cmd, getRedisServerAddress(cr)) + cmd = append(cmd, redis.Redis) + cmd = append(cmd, getRedisServerAddress(rsr.Instance)) if useTLSForRedis { - cmd = append(cmd, "--redis-use-tls") - if isRedisTLSVerificationDisabled(cr) { - cmd = append(cmd, "--redis-insecure-skip-tls-verify") + cmd = append(cmd, redis.RedisUseTLS) + if rsr.Instance.Spec.Redis.DisableTLSVerification { + cmd = append(cmd, redis.RedisInsecureSkipTLSVerify) } else { - cmd = append(cmd, "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt") + cmd = append(cmd, redis.RedisCACertificate, RepoServerTLSRedisCertPath) } } - cmd = append(cmd, "--loglevel") - cmd = append(cmd, getLogLevel(cr.Spec.Repo.LogLevel)) + cmd = append(cmd, LogLevel) + cmd = append(cmd, util.GetLogLevel(rsr.Instance.Spec.Repo.LogLevel)) - cmd = append(cmd, "--logformat") - cmd = append(cmd, getLogFormat(cr.Spec.Repo.LogFormat)) + cmd = append(cmd, LogFormat) + cmd = append(cmd, util.GetLogFormat(rsr.Instance.Spec.Repo.LogFormat)) // *** NOTE *** // Do Not add any new default command line arguments below this. - extraArgs := cr.Spec.Repo.ExtraRepoCommandArgs - err := isMergable(extraArgs, cmd) + extraArgs := rsr.Instance.Spec.Repo.ExtraRepoCommandArgs + err := util.IsMergable(extraArgs, cmd) if err != nil { return cmd } @@ -69,3 +64,16 @@ func (rsr *RepoServerReconciler) GetArgoCDRepoServerReplicas() *int32 { return nil } + +// getRedisServerAddress will return the Redis service address for the given ArgoCD. +func getRedisServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.HA.Enabled { + return getRedisHAProxyAddress(cr) + } + return util.FqdnServiceRef(common.ArgoCDDefaultRedisSuffix, cr.Namespace, common.ArgoCDDefaultRedisPort) +} + +// getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. +func getRedisHAProxyAddress(cr *argoproj.ArgoCD) string { + return util.FqdnServiceRef(redis.RedisHAProxyServiceName, cr.Namespace, common.ArgoCDDefaultRedisPort) +} diff --git a/pkg/util/string.go b/pkg/util/string.go index 06522637a..fad58eb1e 100644 --- a/pkg/util/string.go +++ b/pkg/util/string.go @@ -2,6 +2,7 @@ package util import ( "encoding/base64" + "fmt" "sort" "strings" ) @@ -57,3 +58,13 @@ func GenerateRandomString(s int) (string, error) { } return base64.URLEncoding.EncodeToString(b), nil } + +// isMergable returns error if any of the extraArgs is already part of the default command Arguments. +func IsMergable(extraArgs []string, cmd []string) error { + for _, arg := range extraArgs { + if len(arg) > 2 && arg[:2] == "--" && ContainsString(cmd, arg) { + return fmt.Errorf("arg %s is already part of the default command arguments", arg) + } + } + return nil +} From 64aa2688672ad6681d894e831b78d1d98899dad0 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Tue, 3 Oct 2023 15:20:56 -0400 Subject: [PATCH 23/94] bug: fix heathcheck subkey generation for resources with no group (#1013) * account for empty group during resource customization config subkey generation --------- Signed-off-by: Jaideep Rao --- controllers/argocd/configmap.go | 15 ++++++++++++--- controllers/argocd/configmap_test.go | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/controllers/argocd/configmap.go b/controllers/argocd/configmap.go index e8f6e5a51..1456ec4e0 100644 --- a/controllers/argocd/configmap.go +++ b/controllers/argocd/configmap.go @@ -158,7 +158,10 @@ func getResourceHealthChecks(cr *argoproj.ArgoCD) map[string]string { if cr.Spec.ResourceHealthChecks != nil { resourceHealthChecks := cr.Spec.ResourceHealthChecks for _, healthCustomization := range resourceHealthChecks { - subkey := "resource.customizations.health." + healthCustomization.Group + "_" + healthCustomization.Kind + if healthCustomization.Group != "" { + healthCustomization.Group += "_" + } + subkey := "resource.customizations.health." + healthCustomization.Group + healthCustomization.Kind subvalue := healthCustomization.Check healthCheck[subkey] = subvalue } @@ -181,7 +184,10 @@ func getResourceIgnoreDifferences(cr *argoproj.ArgoCD) (map[string]string, error ignoreDiff[subkey] = subvalue } for _, ignoreDiffCustomization := range resourceIgnoreDiff.ResourceIdentifiers { - subkey := "resource.customizations.ignoreDifferences." + ignoreDiffCustomization.Group + "_" + ignoreDiffCustomization.Kind + if ignoreDiffCustomization.Group != "" { + ignoreDiffCustomization.Group += "_" + } + subkey := "resource.customizations.ignoreDifferences." + ignoreDiffCustomization.Group + ignoreDiffCustomization.Kind bytes, err := yaml.Marshal(ignoreDiffCustomization.Customization) if err != nil { return ignoreDiff, err @@ -199,7 +205,10 @@ func getResourceActions(cr *argoproj.ArgoCD) map[string]string { if cr.Spec.ResourceActions != nil { resourceAction := cr.Spec.ResourceActions for _, actionCustomization := range resourceAction { - subkey := "resource.customizations.actions." + actionCustomization.Group + "_" + actionCustomization.Kind + if actionCustomization.Group != "" { + actionCustomization.Group += "_" + } + subkey := "resource.customizations.actions." + actionCustomization.Group + actionCustomization.Kind subvalue := actionCustomization.Action action[subkey] = subvalue } diff --git a/controllers/argocd/configmap_test.go b/controllers/argocd/configmap_test.go index d00fc3ec3..7dee383a7 100644 --- a/controllers/argocd/configmap_test.go +++ b/controllers/argocd/configmap_test.go @@ -705,6 +705,11 @@ managedfieldsmanagers: Kind: "healthBar", Check: "healthBar", }, + { + Group: "", + Kind: "healthFooBar", + Check: "healthFooBar", + }, } actions := []argoproj.ResourceAction{ { @@ -717,6 +722,11 @@ managedfieldsmanagers: Kind: "actionsBar", Action: "actionsBar", }, + { + Group: "", + Kind: "actionsFooBar", + Action: "actionsFooBar", + }, } ignoreDifferences := argoproj.ResourceIgnoreDifference{ All: &argoproj.IgnoreDifferenceCustomization{ @@ -734,6 +744,15 @@ managedfieldsmanagers: ManagedFieldsManagers: []string{"a", "b"}, }, }, + { + Group: "", + Kind: "ignoreDiffFoo", + Customization: argoproj.IgnoreDifferenceCustomization{ + JqPathExpressions: []string{"a", "b"}, + JsonPointers: []string{"a", "b"}, + ManagedFieldsManagers: []string{"a", "b"}, + }, + }, }, } @@ -757,10 +776,13 @@ managedfieldsmanagers: desiredCM := make(map[string]string) desiredCM["resource.customizations.health.healthFoo_healthFoo"] = "healthFoo" desiredCM["resource.customizations.health.healthBar_healthBar"] = "healthBar" + desiredCM["resource.customizations.health.healthFooBar"] = "healthFooBar" desiredCM["resource.customizations.actions.actionsFoo_actionsFoo"] = "actionsFoo" desiredCM["resource.customizations.actions.actionsBar_actionsBar"] = "actionsBar" + desiredCM["resource.customizations.actions.actionsFooBar"] = "actionsFooBar" desiredCM["resource.customizations.ignoreDifferences.all"] = desiredIgnoreDifferenceCustomization desiredCM["resource.customizations.ignoreDifferences.ignoreDiffBar_ignoreDiffBar"] = desiredIgnoreDifferenceCustomization + desiredCM["resource.customizations.ignoreDifferences.ignoreDiffFoo"] = desiredIgnoreDifferenceCustomization for k, v := range desiredCM { if value, ok := cm.Data[k]; !ok || value != v { From 08e13ecef891681aed3633d0b81f7a45c148b98d Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Tue, 3 Oct 2023 20:01:36 -0400 Subject: [PATCH 24/94] Compiler error fix Signed-off-by: Yi Cai --- common/values.go | 9 ++ controllers/argocd/notifications/configmap.go | 1 - .../argocd/notifications/deployment.go | 1 - controllers/argocd/notifications/role.go | 1 - controllers/argocd/notifications/secret.go | 1 - controllers/argocd/reposerver/constants.go | 2 - controllers/argocd/reposerver/deployment.go | 153 +++++++++--------- controllers/argocd/reposerver/reposerver.go | 18 ++- controllers/argocd/reposerver/service.go | 8 +- .../argocd/reposerver/servicemonitor.go | 8 +- controllers/argocd/reposerver/tlssecret.go | 5 +- 11 files changed, 115 insertions(+), 92 deletions(-) diff --git a/common/values.go b/common/values.go index 910fc117d..f5aee712f 100644 --- a/common/values.go +++ b/common/values.go @@ -69,6 +69,15 @@ const ( VolumeMountPathPlugins = "/home/argocd/cmp-server/plugins" VolumeVarFiles = "var-files" VolumeMountPathVarRunArgocd = "/var/run/argocd" + PortWebhook = "webhook" + SSHKnownHosts = "ssh-known-hosts" + VolumeMountPathSSH = "/app/config/ssh" + GPGKeys = "gpg-keys" + VolumeMountPathGPG = "/app/config/gpg/source" + GPGKeyRing = "gpg-keyring" + VolumeMountPathGPGKeyring = "/app/config/gpg/keys" + VolumeTmp = "tmp" + VolumeMountPathTmp = "/tmp" ) // API group versions and resource kinds diff --git a/controllers/argocd/notifications/configmap.go b/controllers/argocd/notifications/configmap.go index 7d6673d36..c52bd41b4 100644 --- a/controllers/argocd/notifications/configmap.go +++ b/controllers/argocd/notifications/configmap.go @@ -27,7 +27,6 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { if err != nil { nr.Logger.Error(err, "reconcileConfigMap: failed to request configMap", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) - nr.Logger.V(1).Info("reconcileConfigMap: one or more mutations could not be applied") return err } diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index 46ad3a274..59be2249e 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -138,7 +138,6 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { desiredDeployment, err := workloads.RequestDeployment(deploymentRequest) if err != nil { nr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - nr.Logger.V(1).Info("reconcileDeployment: one or more mutations could not be applied") return err } diff --git a/controllers/argocd/notifications/role.go b/controllers/argocd/notifications/role.go index 88b3535d6..78cd8c6cf 100644 --- a/controllers/argocd/notifications/role.go +++ b/controllers/argocd/notifications/role.go @@ -32,7 +32,6 @@ func (nr *NotificationsReconciler) reconcileRole() error { desiredRole, err := permissions.RequestRole(roleRequest) if err != nil { nr.Logger.Error(err, "reconcileRole: failed to request role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) - nr.Logger.V(1).Info("reconcileRole: one or more mutations could not be applied") return err } diff --git a/controllers/argocd/notifications/secret.go b/controllers/argocd/notifications/secret.go index e46a78742..e5ae873c5 100644 --- a/controllers/argocd/notifications/secret.go +++ b/controllers/argocd/notifications/secret.go @@ -28,7 +28,6 @@ func (nr *NotificationsReconciler) reconcileSecret() error { desiredSecret, err := workloads.RequestSecret(secretRequest) if err != nil { nr.Logger.Error(err, "reconcileSecret: failed to request secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) - nr.Logger.V(1).Info("reconcileSecret: one or more mutations could not be applied") return err } diff --git a/controllers/argocd/reposerver/constants.go b/controllers/argocd/reposerver/constants.go index a7ff74b7f..34f947413 100644 --- a/controllers/argocd/reposerver/constants.go +++ b/controllers/argocd/reposerver/constants.go @@ -8,8 +8,6 @@ const ( RepoServerTLSSecretName = "argocd-repo-server-tls" RedisHAProxyServiceName = "redis-ha-haproxy" CopyUtil = "copyutil" - // RepoServerSecretName = "argocd-repo-server-secret" - // RepoServerConfigMapName = "argocd-repo-server-cm" // Commands UidEntryPointSh = "uid_entrypoint.sh" diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 2ef21eab0..db32cb38b 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -2,6 +2,7 @@ package reposerver import ( "fmt" + "reflect" "time" "github.com/argoproj-labs/argocd-operator/common" @@ -20,69 +21,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) -func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *appsv1.Deployment { - desiredDeployment := &appsv1.Deployment{} - - repoServerEnv := rsr.Instance.Spec.Repo.Env - repoServerEnv = util.EnvMerge(repoServerEnv, util.ProxyEnvVars(), false) - - if rsr.Instance.Spec.Repo.ExecTimeout != nil { - repoServerEnv = util.EnvMerge(repoServerEnv, []corev1.EnvVar{{Name: common.ArgoCDExecTimeoutEnvVar, Value: fmt.Sprintf("%ds", *rsr.Instance.Spec.Repo.ExecTimeout)}}, true) - } - - automountToken := false - if rsr.Instance.Spec.Repo.MountSAToken { - automountToken = rsr.Instance.Spec.Repo.MountSAToken - } - - objMeta := metav1.ObjectMeta{ - Name: resourceName, - Namespace: rsr.Instance.Namespace, - Labels: resourceLabels, - } - podSpec := corev1.PodSpec{ - Volumes: rsr.getRepoServerPodVolumes(), - InitContainers: rsr.getRepoSeverInitContainers(), - Containers: rsr.getRepoServerContainers(useTLSForRedis), - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: util.BoolPtr(true), - }, - AutomountServiceAccountToken: &automountToken, - } - - deploymentSpec := appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - Spec: podSpec, - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - common.AppK8sKeyName: resourceName, - }, - }, - }, - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: resourceName, - }, - }, - Replicas: rsr.GetArgoCDRepoServerReplicas(), - } - - desiredDeployment.ObjectMeta = objMeta - desiredDeployment.Spec = deploymentSpec - return desiredDeployment -} - -func (rsr *RepoServerReconciler) getDeploymentRequest(dep appsv1.Deployment) workloads.DeploymentRequest { - deploymentReq := workloads.DeploymentRequest{ - ObjectMeta: dep.ObjectMeta, - Spec: dep.Spec, - Client: rsr.Client, - Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, - } - - return deploymentReq -} - func (rsr *RepoServerReconciler) reconcileDeployment() error { rsr.Logger.Info("reconciling deployment") @@ -99,7 +37,6 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { desiredDeployment, err = workloads.RequestDeployment(deploymentRequest) if err != nil { rsr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - rsr.Logger.V(1).Info("reconcileDeployment: one or more mutations could not be applied") return err } @@ -109,7 +46,7 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { return err } if namespace.DeletionTimestamp != nil { - if err := rsr.DeleteDeployment(desiredDeployment.Name, desiredDeployment.Namespace); err != nil { + if err := rsr.deleteDeployment(desiredDeployment.Name, desiredDeployment.Namespace); err != nil { rsr.Logger.Error(err, "reconcileDeployment: failed to delete deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) } return err @@ -144,23 +81,29 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, - {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, - {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, {&existingDeployment.Spec.Template.Spec.NodeSelector, &desiredDeployment.Spec.Template.Spec.NodeSelector, nil}, {&existingDeployment.Spec.Template.Spec.Tolerations, &desiredDeployment.Spec.Template.Spec.Tolerations, nil}, - {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, - {&existingDeployment.Spec.Template.Labels, &desiredDeployment.Spec.Template.Labels, nil}, - {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, - {&existingDeployment.Spec.Selector, &desiredDeployment.Spec.Selector, nil}, - {&existingDeployment.Labels, &desiredDeployment.Labels, nil}, + {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, // + {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, // + {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, // + {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, // + {&existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, &desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, nil}, // + {&existingDeployment.Spec.Template.Spec.InitContainers, &desiredDeployment.Spec.Template.Spec.InitContainers, nil}, // + {&existingDeployment.Spec.Template.Spec.AutomountServiceAccountToken, &desiredDeployment.Spec.Template.Spec.AutomountServiceAccountToken, nil}, // + {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, // + {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, // } for _, field := range fieldsToCompare { argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deploymentChanged) } + if !reflect.DeepEqual(desiredDeployment.Spec.Template.Spec.Containers[1:], existingDeployment.Spec.Template.Spec.Containers[1:]) { + existingDeployment.Spec.Template.Spec.Containers = append(existingDeployment.Spec.Template.Spec.Containers[0:1], + desiredDeployment.Spec.Template.Spec.Containers[1:]...) + deploymentChanged = true + } + if deploymentChanged { if err = workloads.UpdateDeployment(existingDeployment, rsr.Client); err != nil { @@ -173,7 +116,7 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { return nil } -func (rsr *RepoServerReconciler) DeleteDeployment(name, namespace string) error { +func (rsr *RepoServerReconciler) deleteDeployment(name, namespace string) error { if err := workloads.DeleteDeployment(name, namespace, rsr.Client); err != nil { rsr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) return err @@ -182,6 +125,62 @@ func (rsr *RepoServerReconciler) DeleteDeployment(name, namespace string) error return nil } +func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *appsv1.Deployment { + desiredDeployment := &appsv1.Deployment{} + + automountToken := false + if rsr.Instance.Spec.Repo.MountSAToken { + automountToken = rsr.Instance.Spec.Repo.MountSAToken + } + + objMeta := metav1.ObjectMeta{ + Name: resourceName, + Namespace: rsr.Instance.Namespace, + Labels: resourceLabels, + } + podSpec := corev1.PodSpec{ + Volumes: rsr.getRepoServerPodVolumes(), + InitContainers: rsr.getRepoSeverInitContainers(), + Containers: rsr.getRepoServerContainers(useTLSForRedis), + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: util.BoolPtr(true), + }, + AutomountServiceAccountToken: &automountToken, + } + + deploymentSpec := appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: podSpec, + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + common.AppK8sKeyName: resourceName, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.AppK8sKeyName: resourceName, + }, + }, + Replicas: rsr.GetArgoCDRepoServerReplicas(), + } + + desiredDeployment.ObjectMeta = objMeta + desiredDeployment.Spec = deploymentSpec + return desiredDeployment +} + +func (rsr *RepoServerReconciler) getDeploymentRequest(dep appsv1.Deployment) workloads.DeploymentRequest { + deploymentReq := workloads.DeploymentRequest{ + ObjectMeta: dep.ObjectMeta, + Spec: dep.Spec, + Client: rsr.Client, + Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, + } + + return deploymentReq +} + func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container { initContainers := []corev1.Container{{ Name: CopyUtil, @@ -216,6 +215,10 @@ func (rsr *RepoServerReconciler) getRepoServerContainers(useTLSForRedis bool) [] repoServerEnv := rsr.Instance.Spec.Repo.Env repoServerEnv = util.EnvMerge(repoServerEnv, util.ProxyEnvVars(), false) + if rsr.Instance.Spec.Repo.ExecTimeout != nil { + repoServerEnv = util.EnvMerge(repoServerEnv, []corev1.EnvVar{{Name: common.ArgoCDExecTimeoutEnvVar, Value: fmt.Sprintf("%ds", *rsr.Instance.Spec.Repo.ExecTimeout)}}, true) + } + containers := []corev1.Container{{ Command: rsr.GetArgoRepoServerCommand(useTLSForRedis), Image: argocdcommon.GetArgoContainerImage(rsr.Instance), diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 6f314d91b..e460b8890 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -32,8 +32,13 @@ func (rsr *RepoServerReconciler) Reconcile() error { return err } + if err := rsr.reconcileServiceMonitor(); err != nil { + rsr.Logger.Info("reconciling repo server serviceMonitor") + return err + } + if err := rsr.reconcileTLSSecret(); err != nil { - rsr.Logger.Info("reconciling repo server secret") + rsr.Logger.Info("reconciling repo server tls secret") return err } @@ -49,17 +54,22 @@ func (rsr *RepoServerReconciler) DeleteResources() error { var deletionError error = nil - if err := rsr.DeleteDeployment(resourceName, rsr.Instance.Namespace); err != nil { + if err := rsr.deleteDeployment(resourceName, rsr.Instance.Namespace); err != nil { rsr.Logger.Error(err, "DeleteResources: failed to delete deployment") deletionError = err } - if err := rsr.DeleteTLSSecret(rsr.Instance.Namespace); err != nil { + if err := rsr.deleteTLSSecret(rsr.Instance.Namespace); err != nil { rsr.Logger.Error(err, "DeleteResources: failed to delete secret") deletionError = err } - if err := rsr.DeleteService(resourceName, rsr.Instance.Namespace); err != nil { + if err := rsr.deleteService(resourceName, rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "DeleteResources: failed to delete service") + deletionError = err + } + + if err := rsr.deleteService(resourceName, rsr.Instance.Namespace); err != nil { rsr.Logger.Error(err, "DeleteResources: failed to delete service") deletionError = err } diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index 997151807..b66a86a84 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -30,6 +30,10 @@ func (rsr *RepoServerReconciler) reconcileService() error { } desiredService, err := networking.RequestService(serviceRequest) + if err != nil { + rsr.Logger.Error(err, "reconcileService: failed to request service", "name", desiredService.Name, "namespace", desiredService.Namespace) + return err + } namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) if err != nil { @@ -37,7 +41,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { return err } if namespace.DeletionTimestamp != nil { - if err := rsr.DeleteService(desiredService.Name, desiredService.Namespace); err != nil { + if err := rsr.deleteService(desiredService.Name, desiredService.Namespace); err != nil { rsr.Logger.Error(err, "reconcileService: failed to delete service", "name", desiredService.Name, "namespace", desiredService.Namespace) } return err @@ -75,7 +79,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { return nil } -func (rsr *RepoServerReconciler) DeleteService(name, namespace string) error { +func (rsr *RepoServerReconciler) deleteService(name, namespace string) error { if err := networking.DeleteService(name, namespace, rsr.Client); err != nil { rsr.Logger.Error(err, "DeleteService: failed to delete service", "name", name, "namespace", namespace) return err diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index 00d12d7d8..afac28674 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -24,6 +24,10 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { } desiredServiceMonitor, err := monitoring.RequestServiceMonitor(serviceMonitorRequest) + if err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to request serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + return err + } namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) if err != nil { @@ -31,7 +35,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { return err } if namespace.DeletionTimestamp != nil { - if err := rsr.DeleteServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace); err != nil { + if err := rsr.deleteServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace); err != nil { rsr.Logger.Error(err, "reconcileServiceMonitor: failed to delete serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) } return err @@ -59,7 +63,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { return nil } -func (rsr *RepoServerReconciler) DeleteServiceMonitor(name, namespace string) error { +func (rsr *RepoServerReconciler) deleteServiceMonitor(name, namespace string) error { if err := monitoring.DeleteServiceMonitor(name, namespace, rsr.Client); err != nil { rsr.Logger.Error(err, "DeleteServiceMonitor: failed to delete serviceMonitor", "name", name, "namespace", namespace) return err diff --git a/controllers/argocd/reposerver/tlssecret.go b/controllers/argocd/reposerver/tlssecret.go index a40dbbb99..d1f3b2d17 100644 --- a/controllers/argocd/reposerver/tlssecret.go +++ b/controllers/argocd/reposerver/tlssecret.go @@ -34,7 +34,6 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { desiredSecret, err := workloads.RequestSecret(secretRequest) if err != nil { rsr.Logger.Error(err, "reconcileSecret: failed to request secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) - rsr.Logger.V(1).Info("reconcileSecret: one or more mutations could not be applied") return err } @@ -44,7 +43,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { return err } if namespace.DeletionTimestamp != nil { - if err := rsr.DeleteTLSSecret(desiredSecret.Namespace); err != nil { + if err := rsr.deleteTLSSecret(desiredSecret.Namespace); err != nil { rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) } return err @@ -97,7 +96,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { return nil } -func (rsr *RepoServerReconciler) DeleteTLSSecret(namespace string) error { +func (rsr *RepoServerReconciler) deleteTLSSecret(namespace string) error { if err := workloads.DeleteSecret(RepoServerTLSSecretName, namespace, rsr.Client); err != nil { rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", RepoServerTLSSecretName, "namespace", namespace) return err From ea6d3178ad7149fdab411dce70d094569cf41166 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Thu, 5 Oct 2023 18:33:56 -0400 Subject: [PATCH 25/94] Fixed compiler errors Signed-off-by: Yi Cai --- .../argocd/applicationset/deployment.go | 4 ++-- controllers/argocd/redis/util.go | 15 ++++++++++++ controllers/argocd/reposerver/deployment.go | 4 ++-- controllers/argocd/reposerver/util.go | 23 ++++++------------- pkg/networking/route.go | 18 --------------- 5 files changed, 26 insertions(+), 38 deletions(-) diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 59920ccac..5794f18cf 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -173,7 +173,7 @@ func (asr *ApplicationSetReconciler) getDeploymentRequest(dep appsv1.Deployment) return deploymentReq } -func (asr *ApplicationSetReconciler) getArgoApplicationSetCommand() []string { +func (asr *ApplicationSetReconciler) getApplicationSetCommand() []string { cmd := make([]string, 0) cmd = append(cmd, EntryPointSh) @@ -201,7 +201,7 @@ func (asr *ApplicationSetReconciler) getApplicationSetContainer(addSCMGitlabVolu appSetEnv := asr.Instance.Spec.ApplicationSet.Env appSetEnv = util.EnvMerge(appSetEnv, util.ProxyEnvVars(), false) container := &corev1.Container{ - Command: asr.getArgoApplicationSetCommand(), + Command: asr.getApplicationSetCommand(), Image: argocdcommon.GetArgoContainerImage(asr.Instance), ImagePullPolicy: corev1.PullAlways, Name: AppSetController, diff --git a/controllers/argocd/redis/util.go b/controllers/argocd/redis/util.go index c612c9cfe..079802c11 100644 --- a/controllers/argocd/redis/util.go +++ b/controllers/argocd/redis/util.go @@ -3,14 +3,29 @@ package redis import ( "context" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/util" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) +// getRedisServerAddress will return the Redis service address for the given ArgoCD. +func GetRedisServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.HA.Enabled { + return GetRedisHAProxyAddress(cr.Namespace) + } + return util.FqdnServiceRef(common.ArgoCDDefaultRedisSuffix, cr.Namespace, common.ArgoCDDefaultRedisPort) +} + +// getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. +func GetRedisHAProxyAddress(namespace string) string { + return util.FqdnServiceRef(RedisHAProxyServiceName, namespace, common.ArgoCDDefaultRedisPort) +} + func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, error) { var tlsSecretObj corev1.Secret tlsSecretName := types.NamespacedName{Namespace: instanceNamespace, Name: common.ArgoCDRedisServerTLSSecretName} diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index db32cb38b..9e01efb81 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -162,7 +162,7 @@ func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *apps common.AppK8sKeyName: resourceName, }, }, - Replicas: rsr.GetArgoCDRepoServerReplicas(), + Replicas: rsr.GetRepoServerReplicas(), } desiredDeployment.ObjectMeta = objMeta @@ -220,7 +220,7 @@ func (rsr *RepoServerReconciler) getRepoServerContainers(useTLSForRedis bool) [] } containers := []corev1.Container{{ - Command: rsr.GetArgoRepoServerCommand(useTLSForRedis), + Command: rsr.GetRepoServerCommand(useTLSForRedis), Image: argocdcommon.GetArgoContainerImage(rsr.Instance), ImagePullPolicy: corev1.PullAlways, Name: RepoServerController, diff --git a/controllers/argocd/reposerver/util.go b/controllers/argocd/reposerver/util.go index 9333c5177..f1d96711d 100644 --- a/controllers/argocd/reposerver/util.go +++ b/controllers/argocd/reposerver/util.go @@ -1,7 +1,6 @@ package reposerver import ( - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/redis" "github.com/argoproj-labs/argocd-operator/pkg/util" @@ -20,15 +19,15 @@ func (rsr *RepoServerReconciler) GetRepoServerResources() corev1.ResourceRequire return resources } -// GetArgoRepoServerCommand will return the command for the ArgoCD Repo component. -func (rsr *RepoServerReconciler) GetArgoRepoServerCommand(useTLSForRedis bool) []string { +// GetRepoServerCommand will return the command for the ArgoCD Repo component. +func (rsr *RepoServerReconciler) GetRepoServerCommand(useTLSForRedis bool) []string { cmd := make([]string, 0) cmd = append(cmd, UidEntryPointSh) cmd = append(cmd, RepoServerController) cmd = append(cmd, redis.Redis) - cmd = append(cmd, getRedisServerAddress(rsr.Instance)) + cmd = append(cmd, redis.GetRedisServerAddress(rsr.Instance)) if useTLSForRedis { cmd = append(cmd, redis.RedisUseTLS) @@ -57,7 +56,7 @@ func (rsr *RepoServerReconciler) GetArgoRepoServerCommand(useTLSForRedis bool) [ return cmd } -func (rsr *RepoServerReconciler) GetArgoCDRepoServerReplicas() *int32 { +func (rsr *RepoServerReconciler) GetRepoServerReplicas() *int32 { if rsr.Instance.Spec.Repo.Replicas != nil && *rsr.Instance.Spec.Repo.Replicas >= 0 { return rsr.Instance.Spec.Repo.Replicas } @@ -65,15 +64,7 @@ func (rsr *RepoServerReconciler) GetArgoCDRepoServerReplicas() *int32 { return nil } -// getRedisServerAddress will return the Redis service address for the given ArgoCD. -func getRedisServerAddress(cr *argoproj.ArgoCD) string { - if cr.Spec.HA.Enabled { - return getRedisHAProxyAddress(cr) - } - return util.FqdnServiceRef(common.ArgoCDDefaultRedisSuffix, cr.Namespace, common.ArgoCDDefaultRedisPort) -} - -// getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. -func getRedisHAProxyAddress(cr *argoproj.ArgoCD) string { - return util.FqdnServiceRef(redis.RedisHAProxyServiceName, cr.Namespace, common.ArgoCDDefaultRedisPort) +// GetRepoServerAddress will return the Argo CD repo server address. +func GetRepoServerAddress(name string, namespace string) string { + return util.FqdnServiceRef(util.NameWithSuffix(name, RepoServerControllerComponent), namespace, common.ArgoCDDefaultRepoServerPort) } diff --git a/pkg/networking/route.go b/pkg/networking/route.go index 0b8a58ae7..83098679e 100644 --- a/pkg/networking/route.go +++ b/pkg/networking/route.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/argoproj-labs/argocd-operator/pkg/mutation" - "github.com/argoproj-labs/argocd-operator/pkg/util" routev1 "github.com/openshift/api/route/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -23,23 +22,6 @@ type RouteRequest struct { Client cntrlClient.Client } -var routeAPIFound = false - -// IsRouteAPIAvailable returns true if the Route API is present. -func IsRouteAPIAvailable() bool { - return routeAPIFound -} - -// verifyRouteAPI will verify that the Route API is present. -func VerifyRouteAPI() error { - found, err := util.VerifyAPI(routev1.GroupName, routev1.GroupVersion.Version) - if err != nil { - return err - } - routeAPIFound = found - return nil -} - // newRoute returns a new Route instance for the given ArgoCD. func newRoute(objectMeta metav1.ObjectMeta, spec routev1.RouteSpec) *routev1.Route { return &routev1.Route{ From bbdfc82ee583a3bde839afe8e593adc623d0611e Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Fri, 6 Oct 2023 11:56:32 -0400 Subject: [PATCH 26/94] Added partial unit tests Signed-off-by: Yi Cai --- config/crd/bases/argoproj.io_argocds.yaml | 6442 ----------------- controllers/argocd/argocd_controller.go | 76 +- controllers/argocd/redis/util.go | 11 +- controllers/argocd/reposerver/deployment.go | 2 +- .../argocd/reposerver/reposerver_test.go | 36 + controllers/argocd/reposerver/service.go | 2 +- controllers/argocd/reposerver/service_test.go | 81 + .../argocd/reposerver/servicemonitor.go | 4 +- controllers/argocd/reposerver/tlssecret.go | 35 +- .../argocd/reposerver/tlssecret_test.go | 79 + 10 files changed, 250 insertions(+), 6518 deletions(-) create mode 100644 controllers/argocd/reposerver/reposerver_test.go create mode 100644 controllers/argocd/reposerver/service_test.go create mode 100644 controllers/argocd/reposerver/tlssecret_test.go diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 69cd14b26..c00bc7677 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -5661,6448 +5661,6 @@ spec: type: string type: object type: array - resourceCustomizations: - description: 'ResourceCustomizations customizes resource behavior. - Keys are in the form: group/Kind. Please note that this is being - deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, - and ResourceActions.' - type: string - resourceExclusions: - description: ResourceExclusions is used to completely ignore entire - classes of resource group/kinds. - type: string - resourceHealthChecks: - description: ResourceHealthChecks customizes resource health check - behavior. - items: - description: Resource Customization for custom health check - properties: - check: - type: string - group: - type: string - kind: - type: string - type: object - type: array - resourceIgnoreDifferences: - description: ResourceIgnoreDifferences customizes resource ignore - difference behavior. - properties: - all: - properties: - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - managedFieldsManagers: - items: - type: string - type: array - type: object - resourceIdentifiers: - items: - description: Resource Customization fields for ignore difference - properties: - customization: - properties: - jqPathExpressions: - items: - type: string - type: array - jsonPointers: - items: - type: string - type: array - managedFieldsManagers: - items: - type: string - type: array - type: object - group: - type: string - kind: - type: string - type: object - type: array - type: object - resourceInclusions: - description: ResourceInclusions is used to only include specific group/kinds - in the reconciliation process. - type: string - resourceTrackingMethod: - description: ResourceTrackingMethod defines how Argo CD should track - resources that it manages - type: string - server: - description: Server defines the options for the ArgoCD Server component. - properties: - autoscale: - description: Autoscale defines the autoscale options for the Argo - CD Server component. - properties: - enabled: - description: Enabled will toggle autoscaling support for the - Argo CD Server component. - type: boolean - hpa: - description: HPA defines the HorizontalPodAutoscaler options - for the Argo CD Server component. - properties: - maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. - format: int32 - type: integer - minReplicas: - description: minReplicas is the lower limit for the number - of replicas to which the autoscaler can scale down. It - defaults to 1 pod. minReplicas is allowed to be 0 if - the alpha feature gate HPAScaleToZero is enabled and - at least one Object or External metric is configured. Scaling - is active as long as at least one metric value is available. - format: int32 - type: integer - scaleTargetRef: - description: reference to scaled resource; horizontal - pod autoscaler will learn the current resource consumption - and will set the desired number of pods by using its - Scale subresource. - properties: - apiVersion: - description: API version of the referent - type: string - kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' - type: string - name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' - type: string - required: - - kind - - name - type: object - targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. - format: int32 - type: integer - required: - - maxReplicas - - scaleTargetRef - type: object - required: - - enabled - type: object - env: - description: Env lets you specify environment for API server pods - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - extraCommandArgs: - description: Extra Command arguments that would append to the - Argo CD server command. ExtraCommandArgs will not be added, - if one of these commands is already part of the server command - with same or different value. - items: - type: string - type: array - grpc: - description: GRPC defines the state for the Argo CD Server GRPC - options. - properties: - host: - description: Host is the hostname to use for Ingress/Route - resources. - type: string - ingress: - description: Ingress defines the desired state for the Argo - CD Server GRPC Ingress. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to - apply to the Ingress. - type: object - enabled: - description: Enabled will toggle the creation of the Ingress. - type: boolean - ingressClassName: - description: IngressClassName for the Ingress resource. - type: string - path: - description: Path used for the Ingress resource. - type: string - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - required: - - enabled - type: object - type: object - host: - description: Host is the hostname to use for Ingress/Route resources. - type: string - ingress: - description: Ingress defines the desired state for an Ingress - for the Argo CD Server component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to apply - to the Ingress. - type: object - enabled: - description: Enabled will toggle the creation of the Ingress. - type: boolean - ingressClassName: - description: IngressClassName for the Ingress resource. - type: string - path: - description: Path used for the Ingress resource. - type: string - tls: - description: TLS configuration. Currently the Ingress only - supports a single TLS port, 443. If multiple members of - this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified through - the SNI TLS extension, if the ingress controller fulfilling - the ingress supports SNI. - items: - description: IngressTLS describes the transport layer security - associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included in the - TLS certificate. The values in this list must match - the name/s used in the tlsSecret. Defaults to the - wildcard host setting for the loadbalancer controller - fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret used - to terminate TLS traffic on port 443. Field is left - optional to allow TLS routing based on SNI hostname - alone. If the SNI host in a listener conflicts with - the "Host" header field used by an IngressRule, the - SNI host is used for termination and value of the - Host header is used for routing. - type: string - type: object - type: array - required: - - enabled - type: object - insecure: - description: Insecure toggles the insecure flag. - type: boolean - logFormat: - description: LogFormat refers to the log level to be used by the - ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat - if not configured. Valid options are text or json. - type: string - logLevel: - description: LogLevel refers to the log level to be used by the - ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if - not set. Valid options are debug, info, error, and warn. - type: string - replicas: - description: Replicas defines the number of replicas for argocd-server. - Default is nil. Value should be greater than or equal to 0. - Value will be ignored if Autoscaler is enabled. - format: int32 - type: integer - resources: - description: Resources defines the Compute Resources required - by the container for the Argo CD server component. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - route: - description: Route defines the desired state for an OpenShift - Route for the Argo CD Server component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to use - for the Route resource. - type: object - enabled: - description: Enabled will toggle the creation of the OpenShift - Route. - type: boolean - labels: - additionalProperties: - type: string - description: Labels is the map of labels to use for the Route - resource - type: object - path: - description: Path the router watches for, to route traffic - for to the service. - type: string - tls: - description: TLS provides the ability to configure certificates - and termination for the Route. - properties: - caCertificate: - description: caCertificate provides the cert authority - certificate contents - type: string - certificate: - description: certificate provides certificate contents - type: string - destinationCACertificate: - description: destinationCACertificate provides the contents - of the ca certificate of the final destination. When - using reencrypt termination this file should be provided - in order to have routers use it for health checks on - the secure connection. If this field is not specified, - the router may provide its own destination CA and perform - hostname validation using the short service name (service.namespace.svc), - which allows infrastructure generated certificates to - automatically verify. - type: string - insecureEdgeTerminationPolicy: - description: "insecureEdgeTerminationPolicy indicates - the desired behavior for insecure connections to a route. - While each router may make its own decisions on which - ports to expose, this is normally port 80. \n * Allow - - traffic is sent to the server on the insecure port - (default) * Disable - no traffic is allowed on the insecure - port. * Redirect - clients are redirected to the secure - port." - type: string - key: - description: key provides key file contents - type: string - termination: - description: termination indicates termination type. - type: string - required: - - termination - type: object - wildcardPolicy: - description: WildcardPolicy if any for the route. Currently - only 'Subdomain' or 'None' is allowed. - type: string - required: - - enabled - type: object - service: - description: Service defines the options for the Service backing - the ArgoCD Server component. - properties: - type: - description: Type is the ServiceType to use for the Service - resource. - type: string - required: - - type - type: object - type: object - sourceNamespaces: - description: SourceNamespaces defines the namespaces application resources - are allowed to be created in - items: - type: string - type: array - sso: - description: SSO defines the Single Sign-on configuration for Argo - CD - properties: - dex: - description: Dex contains the configuration for Argo CD dex authentication - properties: - config: - description: Config is the dex connector configuration. - type: string - groups: - description: Optional list of required groups a user must - be a member of - items: - type: string - type: array - image: - description: Image is the Dex container image. - type: string - openShiftOAuth: - description: OpenShiftOAuth enables OpenShift OAuth authentication - for the Dex server. - type: boolean - resources: - description: Resources defines the Compute Resources required - by the container for Dex. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of - compute resources required. If Requests is omitted for - a container, it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - version: - description: Version is the Dex container image tag. - type: string - type: object - image: - description: Deprecated field. Support dropped in v1beta1 version. - Image is the SSO container image. - type: string - keycloak: - description: Keycloak contains the configuration for Argo CD keycloak - authentication - properties: - image: - description: Image is the Keycloak container image. - type: string - resources: - description: Resources defines the Compute Resources required - by the container for Keycloak. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of - compute resources required. If Requests is omitted for - a container, it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - rootCA: - description: Custom root CA certificate for communicating - with the Keycloak OIDC provider - type: string - verifyTLS: - description: VerifyTLS set to false disables strict TLS validation. - type: boolean - version: - description: Version is the Keycloak container image tag. - type: string - type: object - provider: - description: Provider installs and configures the given SSO Provider - with Argo CD. - type: string - resources: - description: Deprecated field. Support dropped in v1beta1 version. - Resources defines the Compute Resources required by the container - for SSO. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - verifyTLS: - description: Deprecated field. Support dropped in v1beta1 version. - VerifyTLS set to false disables strict TLS validation. - type: boolean - version: - description: Deprecated field. Support dropped in v1beta1 version. - Version is the SSO container image tag. - type: string - type: object - statusBadgeEnabled: - description: StatusBadgeEnabled toggles application status badge feature. - type: boolean - tls: - description: TLS defines the TLS options for ArgoCD. - properties: - ca: - description: CA defines the CA options. - properties: - configMapName: - description: ConfigMapName is the name of the ConfigMap containing - the CA Certificate. - type: string - secretName: - description: SecretName is the name of the Secret containing - the CA Certificate and Key. - type: string - type: object - initialCerts: - additionalProperties: - type: string - description: InitialCerts defines custom TLS certificates upon - creation of the cluster for connecting Git repositories via - HTTPS. - type: object - type: object - usersAnonymousEnabled: - description: UsersAnonymousEnabled toggles anonymous user access. - The anonymous users get default role permissions specified argocd-rbac-cm. - type: boolean - version: - description: Version is the tag to use with the ArgoCD container image - for all ArgoCD components. - type: string - type: object - status: - description: ArgoCDStatus defines the observed state of ArgoCD - properties: - applicationController: - description: 'ApplicationController is a simple, high-level summary - of where the Argo CD application controller component is in its - lifecycle. There are four possible ApplicationController values: - Pending: The Argo CD application controller component has been accepted - by the Kubernetes system, but one or more of the required resources - have not been created. Running: All of the required Pods for the - Argo CD application controller component are in a Ready state. Failed: - At least one of the Argo CD application controller component Pods - had a failure. Unknown: The state of the Argo CD application controller - component could not be obtained.' - type: string - applicationSetController: - description: 'ApplicationSetController is a simple, high-level summary - of where the Argo CD applicationSet controller component is in its - lifecycle. There are four possible ApplicationSetController values: - Pending: The Argo CD applicationSet controller component has been - accepted by the Kubernetes system, but one or more of the required - resources have not been created. Running: All of the required Pods - for the Argo CD applicationSet controller component are in a Ready - state. Failed: At least one of the Argo CD applicationSet controller - component Pods had a failure. Unknown: The state of the Argo CD - applicationSet controller component could not be obtained.' - type: string - host: - description: Host is the hostname of the Ingress. - type: string - notificationsController: - description: 'NotificationsController is a simple, high-level summary - of where the Argo CD notifications controller component is in its - lifecycle. There are four possible NotificationsController values: - Pending: The Argo CD notifications controller component has been - accepted by the Kubernetes system, but one or more of the required - resources have not been created. Running: All of the required Pods - for the Argo CD notifications controller component are in a Ready - state. Failed: At least one of the Argo CD notifications controller - component Pods had a failure. Unknown: The state of the Argo CD - notifications controller component could not be obtained.' - type: string - phase: - description: 'Phase is a simple, high-level summary of where the ArgoCD - is in its lifecycle. There are four possible phase values: Pending: - The ArgoCD has been accepted by the Kubernetes system, but one or - more of the required resources have not been created. Available: - All of the resources for the ArgoCD are ready. Failed: At least - one resource has experienced a failure. Unknown: The state of the - ArgoCD phase could not be obtained.' - type: string - redis: - description: 'Redis is a simple, high-level summary of where the Argo - CD Redis component is in its lifecycle. There are four possible - redis values: Pending: The Argo CD Redis component has been accepted - by the Kubernetes system, but one or more of the required resources - have not been created. Running: All of the required Pods for the - Argo CD Redis component are in a Ready state. Failed: At least one - of the Argo CD Redis component Pods had a failure. Unknown: The - state of the Argo CD Redis component could not be obtained.' - type: string - redisTLSChecksum: - description: RedisTLSChecksum contains the SHA256 checksum of the - latest known state of tls.crt and tls.key in the argocd-operator-redis-tls - secret. - type: string - repo: - description: 'Repo is a simple, high-level summary of where the Argo - CD Repo component is in its lifecycle. There are four possible repo - values: Pending: The Argo CD Repo component has been accepted by - the Kubernetes system, but one or more of the required resources - have not been created. Running: All of the required Pods for the - Argo CD Repo component are in a Ready state. Failed: At least one - of the Argo CD Repo component Pods had a failure. Unknown: The - state of the Argo CD Repo component could not be obtained.' - type: string - repoTLSChecksum: - description: RepoTLSChecksum contains the SHA256 checksum of the latest - known state of tls.crt and tls.key in the argocd-repo-server-tls - secret. - type: string - server: - description: 'Server is a simple, high-level summary of where the - Argo CD server component is in its lifecycle. There are four possible - server values: Pending: The Argo CD server component has been accepted - by the Kubernetes system, but one or more of the required resources - have not been created. Running: All of the required Pods for the - Argo CD server component are in a Ready state. Failed: At least - one of the Argo CD server component Pods had a failure. Unknown: - The state of the Argo CD server component could not be obtained.' - type: string - sso: - description: 'SSO is a simple, high-level summary of where the Argo - CD SSO(Dex/Keycloak) component is in its lifecycle. There are four - possible sso values: Pending: The Argo CD SSO component has been - accepted by the Kubernetes system, but one or more of the required - resources have not been created. Running: All of the required Pods - for the Argo CD SSO component are in a Ready state. Failed: At least - one of the Argo CD SSO component Pods had a failure. Unknown: The - state of the Argo CD SSO component could not be obtained.' - type: string - type: object - type: object - served: true - storage: false - subresources: - status: {} - - name: v1beta1 - schema: - openAPIV3Schema: - description: ArgoCD is the Schema for the argocds API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ArgoCDSpec defines the desired state of ArgoCD - properties: - applicationInstanceLabelKey: - description: ApplicationInstanceLabelKey is the key name where Argo - CD injects the app name as a tracking label. - type: string - applicationSet: - description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet - controller should be installed. - properties: - env: - description: Env lets you specify environment for applicationSet - controller pods - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - extraCommandArgs: - description: ExtraCommandArgs allows users to pass command line - arguments to ApplicationSet controller. They get added to default - command line arguments provided by the operator. Please note - that the command line arguments provided as part of ExtraCommandArgs - will not overwrite the default command line arguments. - items: - type: string - type: array - image: - description: Image is the Argo CD ApplicationSet image (optional) - type: string - logLevel: - description: LogLevel describes the log level that should be used - by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel - if not set. Valid options are debug,info, error, and warn. - type: string - resources: - description: Resources defines the Compute Resources required - by the container for ApplicationSet. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - version: - description: Version is the Argo CD ApplicationSet image tag. - (optional) - type: string - webhookServer: - description: WebhookServerSpec defines the options for the ApplicationSet - Webhook Server component. - properties: - host: - description: Host is the hostname to use for Ingress/Route - resources. - type: string - ingress: - description: Ingress defines the desired state for an Ingress - for the Application set webhook component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to - apply to the Ingress. - type: object - enabled: - description: Enabled will toggle the creation of the Ingress. - type: boolean - ingressClassName: - description: IngressClassName for the Ingress resource. - type: string - path: - description: Path used for the Ingress resource. - type: string - tls: - description: TLS configuration. Currently the Ingress - only supports a single TLS port, 443. If multiple members - of this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified - through the SNI TLS extension, if the ingress controller - fulfilling the ingress supports SNI. - items: - description: IngressTLS describes the transport layer - security associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults - to the wildcard host setting for the loadbalancer - controller fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret - used to terminate TLS traffic on port 443. Field - is left optional to allow TLS routing based on - SNI hostname alone. If the SNI host in a listener - conflicts with the "Host" header field used by - an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. - type: string - type: object - type: array - required: - - enabled - type: object - route: - description: Route defines the desired state for an OpenShift - Route for the Application set webhook component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to - use for the Route resource. - type: object - enabled: - description: Enabled will toggle the creation of the OpenShift - Route. - type: boolean - labels: - additionalProperties: - type: string - description: Labels is the map of labels to use for the - Route resource - type: object - path: - description: Path the router watches for, to route traffic - for to the service. - type: string - tls: - description: TLS provides the ability to configure certificates - and termination for the Route. - properties: - caCertificate: - description: caCertificate provides the cert authority - certificate contents - type: string - certificate: - description: certificate provides certificate contents - type: string - destinationCACertificate: - description: destinationCACertificate provides the - contents of the ca certificate of the final destination. When - using reencrypt termination this file should be - provided in order to have routers use it for health - checks on the secure connection. If this field is - not specified, the router may provide its own destination - CA and perform hostname validation using the short - service name (service.namespace.svc), which allows - infrastructure generated certificates to automatically - verify. - type: string - insecureEdgeTerminationPolicy: - description: "insecureEdgeTerminationPolicy indicates - the desired behavior for insecure connections to - a route. While each router may make its own decisions - on which ports to expose, this is normally port - 80. \n * Allow - traffic is sent to the server on - the insecure port (default) * Disable - no traffic - is allowed on the insecure port. * Redirect - clients - are redirected to the secure port." - type: string - key: - description: key provides key file contents - type: string - termination: - description: termination indicates termination type. - type: string - required: - - termination - type: object - wildcardPolicy: - description: WildcardPolicy if any for the route. Currently - only 'Subdomain' or 'None' is allowed. - type: string - required: - - enabled - type: object - type: object - type: object - banner: - description: Banner defines an additional banner to be displayed in - Argo CD UI - properties: - content: - description: Content defines the banner message content to display - type: string - url: - description: URL defines an optional URL to be used as banner - message link - type: string - required: - - content - type: object - configManagementPlugins: - description: ConfigManagementPlugins is used to specify additional - config management plugins. - type: string - controller: - description: Controller defines the Application Controller options - for ArgoCD. - properties: - appSync: - description: "AppSync is used to control the sync frequency, by - default the ArgoCD controller polls Git every 3m. \n Set this - to a duration, e.g. 10m or 600s to control the synchronisation - frequency." - type: string - env: - description: Env lets you specify environment for application - controller pods - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - logFormat: - description: LogFormat refers to the log format used by the Application - Controller component. Defaults to ArgoCDDefaultLogFormat if - not configured. Valid options are text or json. - type: string - logLevel: - description: LogLevel refers to the log level used by the Application - Controller component. Defaults to ArgoCDDefaultLogLevel if not - configured. Valid options are debug, info, error, and warn. - type: string - parallelismLimit: - description: ParallelismLimit defines the limit for parallel kubectl - operations - format: int32 - type: integer - processors: - description: Processors contains the options for the Application - Controller processors. - properties: - operation: - description: Operation is the number of application operation - processors. - format: int32 - type: integer - status: - description: Status is the number of application status processors. - format: int32 - type: integer - type: object - resources: - description: Resources defines the Compute Resources required - by the container for the Application Controller. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - sharding: - description: Sharding contains the options for the Application - Controller sharding configuration. - properties: - clustersPerShard: - description: ClustersPerShard defines the maximum number of - clusters managed by each argocd shard - format: int32 - minimum: 1 - type: integer - dynamicScalingEnabled: - description: DynamicScalingEnabled defines whether dynamic - scaling should be enabled for Application Controller component - type: boolean - enabled: - description: Enabled defines whether sharding should be enabled - on the Application Controller component. - type: boolean - maxShards: - description: MaxShards defines the maximum number of shards - at any given point - format: int32 - type: integer - minShards: - description: MinShards defines the minimum number of shards - at any given point - format: int32 - minimum: 1 - type: integer - replicas: - description: Replicas defines the number of replicas to run - in the Application controller shard. - format: int32 - type: integer - type: object - type: object - dex: - description: Deprecated field. Support dropped in v1beta1 version. - Dex defines the Dex server options for ArgoCD. - properties: - config: - description: Config is the dex connector configuration. - type: string - groups: - description: Optional list of required groups a user must be a - member of - items: - type: string - type: array - image: - description: Image is the Dex container image. - type: string - openShiftOAuth: - description: OpenShiftOAuth enables OpenShift OAuth authentication - for the Dex server. - type: boolean - resources: - description: Resources defines the Compute Resources required - by the container for Dex. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - version: - description: Version is the Dex container image tag. - type: string - type: object - disableAdmin: - description: DisableAdmin will disable the admin user. - type: boolean - extraConfig: - additionalProperties: - type: string - description: "ExtraConfig can be used to add fields to Argo CD configmap - that are not supported by Argo CD CRD. \n Note: ExtraConfig takes - precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` - = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. - In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] - = true." - type: object - gaAnonymizeUsers: - description: GAAnonymizeUsers toggles user IDs being hashed before - sending to google analytics. - type: boolean - gaTrackingID: - description: GATrackingID is the google analytics tracking ID to use. - type: string - grafana: - description: Grafana defines the Grafana server options for ArgoCD. - properties: - enabled: - description: Enabled will toggle Grafana support globally for - ArgoCD. - type: boolean - host: - description: Host is the hostname to use for Ingress/Route resources. - type: string - image: - description: Image is the Grafana container image. - type: string - ingress: - description: Ingress defines the desired state for an Ingress - for the Grafana component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to apply - to the Ingress. - type: object - enabled: - description: Enabled will toggle the creation of the Ingress. - type: boolean - ingressClassName: - description: IngressClassName for the Ingress resource. - type: string - path: - description: Path used for the Ingress resource. - type: string - tls: - description: TLS configuration. Currently the Ingress only - supports a single TLS port, 443. If multiple members of - this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified through - the SNI TLS extension, if the ingress controller fulfilling - the ingress supports SNI. - items: - description: IngressTLS describes the transport layer security - associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included in the - TLS certificate. The values in this list must match - the name/s used in the tlsSecret. Defaults to the - wildcard host setting for the loadbalancer controller - fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret used - to terminate TLS traffic on port 443. Field is left - optional to allow TLS routing based on SNI hostname - alone. If the SNI host in a listener conflicts with - the "Host" header field used by an IngressRule, the - SNI host is used for termination and value of the - Host header is used for routing. - type: string - type: object - type: array - required: - - enabled - type: object - resources: - description: Resources defines the Compute Resources required - by the container for Grafana. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - route: - description: Route defines the desired state for an OpenShift - Route for the Grafana component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to use - for the Route resource. - type: object - enabled: - description: Enabled will toggle the creation of the OpenShift - Route. - type: boolean - labels: - additionalProperties: - type: string - description: Labels is the map of labels to use for the Route - resource - type: object - path: - description: Path the router watches for, to route traffic - for to the service. - type: string - tls: - description: TLS provides the ability to configure certificates - and termination for the Route. - properties: - caCertificate: - description: caCertificate provides the cert authority - certificate contents - type: string - certificate: - description: certificate provides certificate contents - type: string - destinationCACertificate: - description: destinationCACertificate provides the contents - of the ca certificate of the final destination. When - using reencrypt termination this file should be provided - in order to have routers use it for health checks on - the secure connection. If this field is not specified, - the router may provide its own destination CA and perform - hostname validation using the short service name (service.namespace.svc), - which allows infrastructure generated certificates to - automatically verify. - type: string - insecureEdgeTerminationPolicy: - description: "insecureEdgeTerminationPolicy indicates - the desired behavior for insecure connections to a route. - While each router may make its own decisions on which - ports to expose, this is normally port 80. \n * Allow - - traffic is sent to the server on the insecure port - (default) * Disable - no traffic is allowed on the insecure - port. * Redirect - clients are redirected to the secure - port." - type: string - key: - description: key provides key file contents - type: string - termination: - description: termination indicates termination type. - type: string - required: - - termination - type: object - wildcardPolicy: - description: WildcardPolicy if any for the route. Currently - only 'Subdomain' or 'None' is allowed. - type: string - required: - - enabled - type: object - size: - description: Size is the replica count for the Grafana Deployment. - format: int32 - type: integer - version: - description: Version is the Grafana container image tag. - type: string - required: - - enabled - type: object - ha: - description: HA options for High Availability support for the Redis - component. - properties: - enabled: - description: Enabled will toggle HA support globally for Argo - CD. - type: boolean - redisProxyImage: - description: RedisProxyImage is the Redis HAProxy container image. - type: string - redisProxyVersion: - description: RedisProxyVersion is the Redis HAProxy container - image tag. - type: string - resources: - description: Resources defines the Compute Resources required - by the container for HA. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - required: - - enabled - type: object - helpChatText: - description: HelpChatText is the text for getting chat help, defaults - to "Chat now!" - type: string - helpChatURL: - description: HelpChatURL is the URL for getting chat help, this will - typically be your Slack channel for support. - type: string - image: - description: Image is the ArgoCD container image for all ArgoCD components. - type: string - import: - description: Import is the import/restore options for ArgoCD. - properties: - name: - description: Name of an ArgoCDExport from which to import data. - type: string - namespace: - description: Namespace for the ArgoCDExport, defaults to the same - namespace as the ArgoCD. - type: string - required: - - name - type: object - initialRepositories: - description: InitialRepositories to configure Argo CD with upon creation - of the cluster. - type: string - initialSSHKnownHosts: - description: InitialSSHKnownHosts defines the SSH known hosts data - upon creation of the cluster for connecting Git repositories via - SSH. - properties: - excludedefaulthosts: - description: ExcludeDefaultHosts describes whether you would like - to include the default list of SSH Known Hosts provided by ArgoCD. - type: boolean - keys: - description: Keys describes a custom set of SSH Known Hosts that - you would like to have included in your ArgoCD server. - type: string - type: object - kustomizeBuildOptions: - description: KustomizeBuildOptions is used to specify build options/parameters - to use with `kustomize build`. - type: string - kustomizeVersions: - description: KustomizeVersions is a listing of configured versions - of Kustomize to be made available within ArgoCD. - items: - description: KustomizeVersionSpec is used to specify information - about a kustomize version to be used within ArgoCD. - properties: - path: - description: Path is the path to a configured kustomize version - on the filesystem of your repo server. - type: string - version: - description: Version is a configured kustomize version in the - format of vX.Y.Z - type: string - type: object - type: array - monitoring: - description: Monitoring defines whether workload status monitoring - configuration for this instance. - properties: - enabled: - description: Enabled defines whether workload status monitoring - is enabled for this instance or not - type: boolean - required: - - enabled - type: object - nodePlacement: - description: NodePlacement defines NodeSelectors and Taints for Argo - CD workloads - properties: - nodeSelector: - additionalProperties: - type: string - description: NodeSelector is a field of PodSpec, it is a map of - key value pairs used for node selection - type: object - tolerations: - description: Tolerations allow the pods to schedule onto nodes - with matching taints - items: - description: The pod this Toleration is attached to tolerates - any taint that matches the triple using - the matching operator . - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. When specified, allowed - values are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match - all values and all keys. - type: string - operator: - description: Operator represents a key's relationship to - the value. Valid operators are Exists and Equal. Defaults - to Equal. Exists is equivalent to wildcard for value, - so that a pod can tolerate all taints of a particular - category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of - time the toleration (which must be of effect NoExecute, - otherwise this field is ignored) tolerates the taint. - By default, it is not set, which means tolerate the taint - forever (do not evict). Zero and negative values will - be treated as 0 (evict immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - type: object - notifications: - description: Notifications defines whether the Argo CD Notifications - controller should be installed. - properties: - enabled: - description: Enabled defines whether argocd-notifications controller - should be deployed or not - type: boolean - env: - description: Env let you specify environment variables for Notifications - pods - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - image: - description: Image is the Argo CD Notifications image (optional) - type: string - logLevel: - description: LogLevel describes the log level that should be used - by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel - if not set. Valid options are debug,info, error, and warn. - type: string - replicas: - description: Replicas defines the number of replicas to run for - notifications-controller - format: int32 - type: integer - resources: - description: Resources defines the Compute Resources required - by the container for Argo CD Notifications. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - version: - description: Version is the Argo CD Notifications image tag. (optional) - type: string - required: - - enabled - type: object - oidcConfig: - description: OIDCConfig is the OIDC configuration as an alternative - to dex. - type: string - prometheus: - description: Prometheus defines the Prometheus server options for - ArgoCD. - properties: - enabled: - description: Enabled will toggle Prometheus support globally for - ArgoCD. - type: boolean - host: - description: Host is the hostname to use for Ingress/Route resources. - type: string - ingress: - description: Ingress defines the desired state for an Ingress - for the Prometheus component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to apply - to the Ingress. - type: object - enabled: - description: Enabled will toggle the creation of the Ingress. - type: boolean - ingressClassName: - description: IngressClassName for the Ingress resource. - type: string - path: - description: Path used for the Ingress resource. - type: string - tls: - description: TLS configuration. Currently the Ingress only - supports a single TLS port, 443. If multiple members of - this list specify different hosts, they will be multiplexed - on the same port according to the hostname specified through - the SNI TLS extension, if the ingress controller fulfilling - the ingress supports SNI. - items: - description: IngressTLS describes the transport layer security - associated with an Ingress. - properties: - hosts: - description: Hosts are a list of hosts included in the - TLS certificate. The values in this list must match - the name/s used in the tlsSecret. Defaults to the - wildcard host setting for the loadbalancer controller - fulfilling this Ingress, if left unspecified. - items: - type: string - type: array - x-kubernetes-list-type: atomic - secretName: - description: SecretName is the name of the secret used - to terminate TLS traffic on port 443. Field is left - optional to allow TLS routing based on SNI hostname - alone. If the SNI host in a listener conflicts with - the "Host" header field used by an IngressRule, the - SNI host is used for termination and value of the - Host header is used for routing. - type: string - type: object - type: array - required: - - enabled - type: object - route: - description: Route defines the desired state for an OpenShift - Route for the Prometheus component. - properties: - annotations: - additionalProperties: - type: string - description: Annotations is the map of annotations to use - for the Route resource. - type: object - enabled: - description: Enabled will toggle the creation of the OpenShift - Route. - type: boolean - labels: - additionalProperties: - type: string - description: Labels is the map of labels to use for the Route - resource - type: object - path: - description: Path the router watches for, to route traffic - for to the service. - type: string - tls: - description: TLS provides the ability to configure certificates - and termination for the Route. - properties: - caCertificate: - description: caCertificate provides the cert authority - certificate contents - type: string - certificate: - description: certificate provides certificate contents - type: string - destinationCACertificate: - description: destinationCACertificate provides the contents - of the ca certificate of the final destination. When - using reencrypt termination this file should be provided - in order to have routers use it for health checks on - the secure connection. If this field is not specified, - the router may provide its own destination CA and perform - hostname validation using the short service name (service.namespace.svc), - which allows infrastructure generated certificates to - automatically verify. - type: string - insecureEdgeTerminationPolicy: - description: "insecureEdgeTerminationPolicy indicates - the desired behavior for insecure connections to a route. - While each router may make its own decisions on which - ports to expose, this is normally port 80. \n * Allow - - traffic is sent to the server on the insecure port - (default) * Disable - no traffic is allowed on the insecure - port. * Redirect - clients are redirected to the secure - port." - type: string - key: - description: key provides key file contents - type: string - termination: - description: termination indicates termination type. - type: string - required: - - termination - type: object - wildcardPolicy: - description: WildcardPolicy if any for the route. Currently - only 'Subdomain' or 'None' is allowed. - type: string - required: - - enabled - type: object - size: - description: Size is the replica count for the Prometheus StatefulSet. - format: int32 - type: integer - required: - - enabled - type: object - rbac: - description: RBAC defines the RBAC configuration for Argo CD. - properties: - defaultPolicy: - description: DefaultPolicy is the name of the default role which - Argo CD will falls back to, when authorizing API requests (optional). - If omitted or empty, users may be still be able to login, but - will see no apps, projects, etc... - type: string - policy: - description: 'Policy is CSV containing user-defined RBAC policies - and role definitions. Policy rules are in the form: p, subject, - resource, action, object, effect Role definitions and bindings - are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md - for additional information.' - type: string - policyMatcherMode: - description: PolicyMatcherMode configures the matchers function - mode for casbin. There are two options for this, 'glob' for - glob matcher or 'regex' for regex matcher. - type: string - scopes: - description: 'Scopes controls which OIDC scopes to examine during - rbac enforcement (in addition to `sub` scope). If omitted, defaults - to: ''[groups]''.' - type: string - type: object - redis: - description: Redis defines the Redis server options for ArgoCD. - properties: - autotls: - description: 'AutoTLS specifies the method to use for automatic - TLS configuration for the redis server The value specified here - can currently be: - openshift - Use the OpenShift service CA - to request TLS config' - type: string - disableTLSVerification: - description: DisableTLSVerification defines whether redis server - API should be accessed using strict TLS validation - type: boolean - image: - description: Image is the Redis container image. - type: string - resources: - description: Resources defines the Compute Resources required - by the container for Redis. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - version: - description: Version is the Redis container image tag. - type: string - type: object - repo: - description: Repo defines the repo server options for Argo CD. - properties: - autotls: - description: 'AutoTLS specifies the method to use for automatic - TLS configuration for the repo server The value specified here - can currently be: - openshift - Use the OpenShift service CA - to request TLS config' - type: string - env: - description: Env lets you specify environment for repo server - pods - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be a - C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. If - a variable cannot be resolved, the reference in the input - string will be unchanged. Double $$ are reduced to a single - $, which allows for escaping the $(VAR_NAME) syntax: i.e. - "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless - of whether the variable exists or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports metadata.name, - metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: only - resources limits and requests (limits.cpu, limits.memory, - limits.ephemeral-storage, requests.cpu, requests.memory - and requests.ephemeral-storage) are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - execTimeout: - description: ExecTimeout specifies the timeout in seconds for - tool execution - type: integer - extraRepoCommandArgs: - description: Extra Command arguments allows users to pass command - line arguments to repo server workload. They get added to default - command line arguments provided by the operator. Please note - that the command line arguments provided as part of ExtraRepoCommandArgs - will not overwrite the default command line arguments. - items: - type: string - type: array - image: - description: Image is the ArgoCD Repo Server container image. - type: string - initContainers: - description: InitContainers defines the list of initialization - containers for the repo server deployment - items: - description: A single application container that you want to - run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) - syntax: i.e. "$$(VAR_NAME)" will produce the string literal - "$(VAR_NAME)". Escaped references will never be expanded, - regardless of whether the variable exists or not. Cannot - be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not - provided. Variable references $(VAR_NAME) are expanded - using the container''s environment. If a variable cannot - be resolved, the reference in the input string will be - unchanged. Double $$ are reduced to a single $, which - allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" - will produce the string literal "$(VAR_NAME)". Escaped - references will never be expanded, regardless of whether - the variable exists or not. Cannot be updated. More info: - https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previously defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - Double $$ are reduced to a single $, which allows - for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" - will produce the string literal "$(VAR_NAME)". Escaped - references will never be expanded, regardless of - whether the variable exists or not. Defaults to - "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in - the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of - the exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or - its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported as - an event when the container is starting. When a key exists - in multiple sources, the value associated with the last - source will take precedence. Values defined by an Env - with a duplicate key will take precedence. Cannot be updated. - items: - description: EnvFromSource represents the source of a - set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret must be - defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management - to default or override container images in workload controllers - like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent - otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should take - in response to container lifecycle events. Cannot be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according to - its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') in - the container's filesystem. The command is - simply exec'd, it is not run inside a shell, - so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is - treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to - the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward - compatibility. There are no validation of this - field and lifecycle hooks will fail in runtime - when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before a - container is terminated due to an API request or management - event such as liveness/startup probe failure, preemption, - resource contention, etc. The handler is not called - if the container crashes or exits. The Pod''s termination - grace period countdown begins before the PreStop hook - is executed. Regardless of the outcome of the handler, - the container will eventually terminate within the - Pod''s termination grace period (unless delayed by - finalizers). Other management of the container blocks - until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') in - the container's filesystem. The command is - simply exec'd, it is not run inside a shell, - so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is - treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to - the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward - compatibility. There are no validation of this - field and lifecycle hooks will fail in runtime - when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service - to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided - by the pod spec. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). This is - a beta field and requires enabling ProbeTerminationGracePeriod - feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. - items: - description: ContainerPort represents a network port in - a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, 0 - < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in a - pod must have a unique name. Name for the port that - can be referred to by services. - type: string - protocol: - default: TCP - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if the - probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service - to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided - by the pod spec. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). This is - a beta field and requires enabling ProbeTerminationGracePeriod - feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - securityContext: - description: 'SecurityContext defines the security options - the container should be run with. If set, the fields of - SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that - this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. Note that this - field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if - it does. If unset or false, no such validation will - be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is - windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & - container level, the container options override the - pod options. Note that this field cannot be set when - spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. - The profile must be preconfigured on the node - to work. Must be a descending path, relative to - the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n - Localhost - a profile defined in a file on the - node should be used. RuntimeDefault - the container - runtime default profile should be used. Unconfined - - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has successfully - initialized. If specified, no other probes are executed - until this completes successfully. If this probe fails, - the Pod will be restarted, just as if the livenessProbe - failed. This can be used to provide different probe parameters - at the beginning of a Pod''s lifecycle, when it might - take a long time to load data or warm a cache, than during - steady-state operation. This cannot be updated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service - to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided - by the pod spec. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). This is - a beta field and requires enabling ProbeTerminationGracePeriod - feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a buffer - for stdin in the container runtime. If this is not set, - reads from stdin in the container will always result in - EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is empty - until the first client attaches to stdin, and then remains - open and accepts data until the client disconnects, at - which time stdin is closed and remains closed until the - container is restarted. If this flag is false, a container - processes that reads from stdin will never receive an - EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written is - mounted into the container''s filesystem. Message written - is intended to be brief final status, such as an assertion - failure message. Will be truncated by the node if greater - than 4096 bytes. The total message length across all containers - will be limited to 12kb. Defaults to /dev/termination-log. - Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last chunk - of container log output if the termination message file - is empty and the container exited with an error. The log - output is limited to 2048 bytes or 80 lines, whichever - is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a TTY - for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which the - volume should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and the - other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults to - "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the container's - environment. Defaults to "" (volume's root). SubPathExpr - and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which might - be configured in the container image. Cannot be updated. - type: string - required: - - name - type: object - type: array - logFormat: - description: LogFormat describes the log format that should be - used by the Repo Server. Defaults to ArgoCDDefaultLogFormat - if not configured. Valid options are text or json. - type: string - logLevel: - description: LogLevel describes the log level that should be used - by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not - set. Valid options are debug, info, error, and warn. - type: string - mountsatoken: - description: MountSAToken describes whether you would like to - have the Repo server mount the service account token - type: boolean - replicas: - description: Replicas defines the number of replicas for argocd-repo-server. - Value should be greater than or equal to 0. Default is nil. - format: int32 - type: integer - resources: - description: Resources defines the Compute Resources required - by the container for Redis. - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - serviceaccount: - description: ServiceAccount defines the ServiceAccount user that - you would like the Repo server to use - type: string - sidecarContainers: - description: SidecarContainers defines the list of sidecar containers - for the repo server deployment - items: - description: A single application container that you want to - run within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) - syntax: i.e. "$$(VAR_NAME)" will produce the string literal - "$(VAR_NAME)". Escaped references will never be expanded, - regardless of whether the variable exists or not. Cannot - be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not - provided. Variable references $(VAR_NAME) are expanded - using the container''s environment. If a variable cannot - be resolved, the reference in the input string will be - unchanged. Double $$ are reduced to a single $, which - allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" - will produce the string literal "$(VAR_NAME)". Escaped - references will never be expanded, regardless of whether - the variable exists or not. Cannot be updated. More info: - https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the - container. Cannot be updated. - items: - description: EnvVar represents an environment variable - present in a Container. - properties: - name: - description: Name of the environment variable. Must - be a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are - expanded using the previously defined environment - variables in the container and any service environment - variables. If a variable cannot be resolved, the - reference in the input string will be unchanged. - Double $$ are reduced to a single $, which allows - for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" - will produce the string literal "$(VAR_NAME)". Escaped - references will never be expanded, regardless of - whether the variable exists or not. Defaults to - "".' - type: string - valueFrom: - description: Source for the environment variable's - value. Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in - the specified API version. - type: string - required: - - fieldPath - type: object - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of - the exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - secretKeyRef: - description: Selects a key of a secret in the - pod's namespace - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or - its key must be defined - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must - be a C_IDENTIFIER. All invalid keys will be reported as - an event when the container is starting. When a key exists - in multiple sources, the value associated with the last - source will take precedence. Values defined by an Env - with a duplicate key will take precedence. Cannot be updated. - items: - description: EnvFromSource represents the source of a - set of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap must - be defined - type: boolean - type: object - prefix: - description: An optional identifier to prepend to - each key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret must be - defined - type: boolean - type: object - type: object - type: array - image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management - to default or override container images in workload controllers - like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent - otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should take - in response to container lifecycle events. Cannot be updated. - properties: - postStart: - description: 'PostStart is called immediately after - a container is created. If the handler fails, the - container is terminated and restarted according to - its restart policy. Other management of the container - blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') in - the container's filesystem. The command is - simply exec'd, it is not run inside a shell, - so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is - treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to - the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward - compatibility. There are no validation of this - field and lifecycle hooks will fail in runtime - when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before a - container is terminated due to an API request or management - event such as liveness/startup probe failure, preemption, - resource contention, etc. The handler is not called - if the container crashes or exits. The Pod''s termination - grace period countdown begins before the PreStop hook - is executed. Regardless of the outcome of the handler, - the container will eventually terminate within the - Pod''s termination grace period (unless delayed by - finalizers). Other management of the container blocks - until the hook completes or until the termination - grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to - execute inside the container, the working - directory for the command is root ('/') in - the container's filesystem. The command is - simply exec'd, it is not run inside a shell, - so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is - treated as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request - to perform. - properties: - host: - description: Host name to connect to, defaults - to the pod IP. You probably want to set "Host" - in httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom - header to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to - the host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward - compatibility. There are no validation of this - field and lifecycle hooks will fail in runtime - when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect - to, defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service - to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided - by the pod spec. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). This is - a beta field and requires enabling ProbeTerminationGracePeriod - feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. - items: - description: ContainerPort represents a network port in - a single container. - properties: - containerPort: - description: Number of port to expose on the pod's - IP address. This must be a valid port number, 0 - < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port - to. - type: string - hostPort: - description: Number of port to expose on the host. - If specified, this must be a valid port number, - 0 < x < 65536. If HostNetwork is specified, this - must match ContainerPort. Most containers do not - need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in a - pod must have a unique name. Name for the port that - can be referred to by services. - type: string - protocol: - default: TCP - description: Protocol for port. Must be UDP, TCP, - or SCTP. Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if the - probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service - to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided - by the pod spec. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). This is - a beta field and requires enabling ProbeTerminationGracePeriod - feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of - compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - securityContext: - description: 'SecurityContext defines the security options - the container should be run with. If set, the fields of - SecurityContext override the equivalent fields of PodSecurityContext. - More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent - process. This bool directly controls if the no_new_privs - flag will be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be - set when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running - containers. Defaults to the default set of capabilities - granted by the container runtime. Note that this field - cannot be set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent - to root on the host. Defaults to false. Note that - this field cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount - to use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only - root filesystem. Default is false. Note that this - field cannot be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as - a non-root user. If true, the Kubelet will validate - the image at runtime to ensure that it does not run - as UID 0 (root) and fail to start the container if - it does. If unset or false, no such validation will - be performed. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name - is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the - container. If unspecified, the container runtime will - allocate a random SELinux context for each container. May - also be set in PodSecurityContext. If set in both - SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is - windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & - container level, the container options override the - pod options. Note that this field cannot be set when - spec.os.name is windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile - defined in a file on the node should be used. - The profile must be preconfigured on the node - to work. Must be a descending path, relative to - the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". - type: string - type: - description: "type indicates which kind of seccomp - profile will be applied. Valid options are: \n - Localhost - a profile defined in a file on the - node should be used. RuntimeDefault - the container - runtime default profile should be used. Unconfined - - no profile should be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to - all containers. If unspecified, the options from the - PodSecurityContext will be used. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set - when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA - admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec - named by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name - of the GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true - then HostNetwork must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the - entrypoint of the container process. Defaults - to the user specified in image metadata if unspecified. - May also be set in PodSecurityContext. If set - in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has successfully - initialized. If specified, no other probes are executed - until this completes successfully. If this probe fails, - the Pod will be restarted, just as if the livenessProbe - failed. This can be used to provide different probe parameters - at the beginning of a Pod''s lifecycle, when it might - take a long time to load data or warm a cache, than during - steady-state operation. This cannot be updated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service - to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container - has started before liveness probes are initiated. - More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum - value is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving - a TCP port. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and - the time when the processes are forcibly halted with - a kill signal. Set this value longer than the expected - cleanup time for your process. If this value is nil, - the pod's terminationGracePeriodSeconds will be used. - Otherwise, this value overrides the value provided - by the pod spec. Value must be non-negative integer. - The value zero indicates stop immediately via the - kill signal (no opportunity to shut down). This is - a beta field and requires enabling ProbeTerminationGracePeriod - feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds - is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe - times out. Defaults to 1 second. Minimum value is - 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a buffer - for stdin in the container runtime. If this is not set, - reads from stdin in the container will always result in - EOF. Default is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close - the stdin channel after it has been opened by a single - attach. When stdin is true the stdin stream will remain - open across multiple attach sessions. If stdinOnce is - set to true, stdin is opened on container start, is empty - until the first client attaches to stdin, and then remains - open and accepts data until the client disconnects, at - which time stdin is closed and remains closed until the - container is restarted. If this flag is false, a container - processes that reads from stdin will never receive an - EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which - the container''s termination message will be written is - mounted into the container''s filesystem. Message written - is intended to be brief final status, such as an assertion - failure message. Will be truncated by the node if greater - than 4096 bytes. The total message length across all containers - will be limited to 12kb. Defaults to /dev/termination-log. - Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should - be populated. File will use the contents of terminationMessagePath - to populate the container status message on both success - and failure. FallbackToLogsOnError will use the last chunk - of container log output if the termination message file - is empty and the container exited with an error. The log - output is limited to 2048 bytes or 80 lines, whichever - is smaller. Defaults to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a TTY - for itself, also requires 'stdin' to be true. Default - is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices - to be used by the container. - items: - description: volumeDevice describes a mapping of a raw - block device within a container. - properties: - devicePath: - description: devicePath is the path inside of the - container that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which the - volume should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts - are propagated from the host to container and the - other way around. When not set, MountPropagationNone - is used. This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write - otherwise (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the - container's volume should be mounted. Defaults to - "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from - which the container's volume should be mounted. - Behaves similarly to SubPath but environment variable - references $(VAR_NAME) are expanded using the container's - environment. Defaults to "" (volume's root). SubPathExpr - and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which might - be configured in the container image. Cannot be updated. - type: string - required: - - name - type: object - type: array - verifytls: - description: VerifyTLS defines whether repo server API should - be accessed using strict TLS validation - type: boolean - version: - description: Version is the ArgoCD Repo Server container image - tag. - type: string - volumeMounts: - description: VolumeMounts adds volumeMounts to the repo server - container - items: - description: VolumeMount describes a mounting of a Volume within - a container. - properties: - mountPath: - description: Path within the container at which the volume - should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are - propagated from the host to container and the other way - around. When not set, MountPropagationNone is used. This - field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which - the container's volume should be mounted. Behaves similarly - to SubPath but environment variable references $(VAR_NAME) - are expanded using the container's environment. Defaults - to "" (volume's root). SubPathExpr and SubPath are mutually - exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - description: Volumes adds volumes to the repo server deployment - items: - description: Volume represents a named volume in a pod that - may be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk - resource that is attached to a kubelet''s host machine - and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' - format: int32 - type: integer - readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: boolean - volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: string - required: - - volumeID - type: object - azureDisk: - description: AzureDisk represents an Azure Data Disk mount - on the host and bind mount to the pod. - properties: - cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' - type: string - diskName: - description: The Name of the data disk in the blob storage - type: string - diskURI: - description: The URI the data disk in the blob storage - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults - to shared' - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: AzureFile represents an Azure File Service - mount on the host and bind mount to the pod. - properties: - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: the name of secret that contains Azure - Storage Account Name and Key - type: string - shareName: - description: Share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: CephFS represents a Ceph FS mount on the host - that shares a pod's lifetime - properties: - monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - items: - type: string - type: array - path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: boolean - secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - required: - - monitors - type: object - cinder: - description: 'Cinder represents a cinder volume attached - and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - properties: - fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: boolean - secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - required: - - volumeID - type: object - configMap: - description: ConfigMap represents a configMap that should - populate this volume - properties: - defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. - Paths must be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path within a - volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or its keys - must be defined - type: boolean - type: object - csi: - description: CSI (Container Storage Interface) represents - ephemeral storage that is handled by certain external - CSI drivers (Beta feature). - properties: - driver: - description: Driver is the name of the CSI driver that - handles this volume. Consult with your admin for the - correct name as registered in the cluster. - type: string - fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. - type: string - nodePublishSecretRef: - description: NodePublishSecretRef is a reference to - the secret object containing sensitive information - to pass to the CSI driver to complete the CSI NodePublishVolume - and NodeUnpublishVolume calls. This field is optional, - and may be empty if no secret is required. If the - secret object contains more than one secret, all secret - references are passed. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: VolumeAttributes stores driver-specific - properties that are passed to the CSI driver. Consult - your driver's documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: DownwardAPI represents downward API about the - pod that should populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created - files by default. Must be a Optional: mode bits used - to set permissions on created files by default. Must - be an octal value between 0000 and 0777 or a decimal - value between 0 and 511. YAML accepts both octal and - decimal values, JSON requires decimal values for mode - bits. Defaults to 0644. Directories within the path - are not affected by this setting. This might be in - conflict with other options that affect the file mode, - like fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - items: - description: Items is a list of downward API volume - file - items: - description: DownwardAPIVolumeFile represents information - to create the file containing the pod field - properties: - fieldRef: - description: 'Required: Selects a field of the - pod: only annotations, labels, name and namespace - are supported.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in - the specified API version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits used to set - permissions on this file, must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must not - be absolute or contain the ''..'' path. Must - be utf-8 encoded. The first item of the relative - path must not start with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required for - volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of - the exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - emptyDir: - description: 'EmptyDir represents a temporary directory - that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - properties: - medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - description: "Ephemeral represents a volume that is handled - by a cluster storage driver. The volume's lifecycle is - tied to the pod that defines it - it will be created before - the pod starts, and deleted when the pod is removed. \n - Use this if: a) the volume is only needed while the pod - runs, b) features of normal volumes like restoring from - snapshot or capacity tracking are needed, c) the storage - driver is specified through a storage class, and d) the - storage driver supports dynamic volume provisioning through - \ a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between this - volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim - or one of the vendor-specific APIs for volumes that persist - for longer than the lifecycle of an individual pod. \n - Use CSI for light-weight local ephemeral volumes if the - CSI driver is meant to be used that way - see the documentation - of the driver for more information. \n A pod can use both - types of ephemeral volumes and persistent volumes at the - same time." - properties: - volumeClaimTemplate: - description: "Will be used to create a stand-alone PVC - to provision the volume. The pod in which this EphemeralVolumeSource - is embedded will be the owner of the PVC, i.e. the - PVC will be deleted together with the pod. The name - of the PVC will be `-` where - `` is the name from the `PodSpec.Volumes` - array entry. Pod validation will reject the pod if - the concatenated name is not valid for a PVC (for - example, too long). \n An existing PVC with that name - that is not owned by the pod will *not* be used for - the pod to avoid using an unrelated volume by mistake. - Starting the pod is then blocked until the unrelated - PVC is removed. If such a pre-created PVC is meant - to be used by the pod, the PVC has to updated with - an owner reference to the pod once the pod exists. - Normally this should not be necessary, but it may - be useful when manually reconstructing a broken cluster. - \n This field is read-only and no changes will be - made by Kubernetes to the PVC after it has been created. - \n Required, must not be nil." - properties: - metadata: - description: May contain labels and annotations - that will be copied into the PVC when creating - it. No other fields are allowed and will be rejected - during validation. - type: object - spec: - description: The specification for the PersistentVolumeClaim. - The entire content is copied unchanged into the - PVC that gets created from this template. The - same fields as in a PersistentVolumeClaim are - also valid here. - properties: - accessModes: - description: 'AccessModes contains the desired - access modes the volume should have. More - info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller - can support the specified data source, it - will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' - properties: - apiGroup: - description: APIGroup is the group for the - resource being referenced. If APIGroup - is not specified, the specified Kind must - be in the core API group. For any other - third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - required: - - kind - - name - type: object - dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field - and as such if both fields are non-empty, - they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves - all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the - resource being referenced. If APIGroup - is not specified, the specified Kind must - be in the core API group. For any other - third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource - being referenced - type: string - name: - description: Name is the name of resource - being referenced - type: string - required: - - kind - - name - type: object - resources: - description: 'Resources represents the minimum - resources the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify - resource requirements that are lower than - previous value but must still be higher than - capacity recorded in the status field of the - claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum - amount of compute resources allowed. More - info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. - If Requests is omitted for a container, - it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: A label query over volumes to consider - for binding. - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The requirements - are ANDed. - items: - description: A label selector requirement - is a selector that contains values, - a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key - that the selector applies to. - type: string - operator: - description: operator represents a - key's relationship to a set of values. - Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of - string values. If the operator is - In or NotIn, the values array must - be non-empty. If the operator is - Exists or DoesNotExist, the values - array must be empty. This array - is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator - is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of - volume is required by the claim. Value of - Filesystem is implied when not included in - claim spec. - type: string - volumeName: - description: VolumeName is the binding reference - to the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - fc: - description: FC represents a Fibre Channel resource that - is attached to a kubelet's host machine and then exposed - to the pod. - properties: - fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' - type: string - lun: - description: 'Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' - items: - type: string - type: array - wwids: - description: 'Optional: FC volume world wide identifiers - (wwids) Either wwids or combination of targetWWNs - and lun must be set, but not both simultaneously.' - items: - type: string - type: array - type: object - flexVolume: - description: FlexVolume represents a generic volume resource - that is provisioned/attached using an exec based plugin. - properties: - driver: - description: Driver is the name of the driver to use - for this volume. - type: string - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. - type: string - options: - additionalProperties: - type: string - description: 'Optional: Extra command options if any.' - type: object - readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - required: - - driver - type: object - flocker: - description: Flocker represents a Flocker volume attached - to a kubelet's host machine. This depends on the Flocker - control service being running - properties: - datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated - type: string - datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource - that is attached to a kubelet''s host machine and then - exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - format: int32 - type: integer - pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More info: - https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: boolean - required: - - pdName - type: object - gitRepo: - description: 'GitRepo represents a git repository at a particular - revision. DEPRECATED: GitRepo is deprecated. To provision - a container with a git repo, mount an EmptyDir into an - InitContainer that clones the repo using git, then mount - the EmptyDir into the Pod''s container.' - properties: - directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, - if specified, the volume will contain the git repository - in the subdirectory with the given name. - type: string - repository: - description: Repository URL - type: string - revision: - description: Commit hash for the specified revision. - type: string - required: - - repository - type: object - glusterfs: - description: 'Glusterfs represents a Glusterfs mount on - the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' - properties: - endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - path: - description: 'Path is the Glusterfs volume path. More - info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - readOnly: - description: 'ReadOnly here will force the Glusterfs - volume to be mounted with read-only permissions. Defaults - to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: 'HostPath represents a pre-existing file or - directory on the host machine that is directly exposed - to the container. This is generally used for system agents - or other privileged things that are allowed to see the - host machine. Most containers will NOT need this. More - info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - --- TODO(jonesdl) We need to restrict who can use host - directory mounts and who can/can not mount host directories - as read/write.' - properties: - path: - description: 'Path of the directory on the host. If - the path is a symlink, it will follow the link to - the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - type: - description: 'Type for HostPath Volume Defaults to "" - More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - required: - - path - type: object - iscsi: - description: 'ISCSI represents an ISCSI Disk resource that - is attached to a kubelet''s host machine and then exposed - to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' - properties: - chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication - type: boolean - chapAuthSession: - description: whether support iSCSI Session CHAP authentication - type: boolean - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. - type: string - iqn: - description: Target iSCSI Qualified Name. - type: string - iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). - type: string - lun: - description: iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - readOnly: - description: ReadOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. - type: boolean - secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - nfs: - description: 'NFS represents an NFS mount on the host that - shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - properties: - path: - description: 'Path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'ReadOnly here will force the NFS export - to be mounted with read-only permissions. Defaults - to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'Server is the hostname or IP address of - the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents - a reference to a PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim - in the same namespace as the pod using this volume. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController - persistent disk attached and mounted on kubelets host - machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - pdID: - description: ID that identifies Photon Controller persistent - disk - type: string - required: - - pdID - type: object - portworxVolume: - description: PortworxVolume represents a portworx volume - attached and mounted on kubelets host machine - properties: - fsType: - description: FSType represents the filesystem type to - mount Must be a filesystem type supported by the host - operating system. Ex. "ext4", "xfs". Implicitly inferred - to be "ext4" if unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: VolumeID uniquely identifies a Portworx - volume - type: string - required: - - volumeID - type: object - projected: - description: Items for all in one resources secrets, configmaps, - and downward API - properties: - defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. - format: int32 - type: integer - sources: - description: list of volume projections - items: - description: Projection that may be projected along - with other supported volume types - properties: - configMap: - description: information about the configMap data - to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - ConfigMap will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed keys - will be projected into the specified paths, - and unlisted keys will not be present. If - a key is specified which is not present - in the ConfigMap, the volume setup will - error unless it is marked optional. Paths - must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain - the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - downwardAPI: - description: information about the downwardAPI - data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects a field - of the pod: only annotations, labels, - name and namespace are supported.' - properties: - apiVersion: - description: Version of the schema - the FieldPath is written in terms - of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to - select in the specified API version. - type: string - required: - - fieldPath - type: object - mode: - description: 'Optional: mode bits used - to set permissions on this file, must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the - relative path name of the file to - be created. Must not be absolute or - contain the ''..'' path. Must be utf-8 - encoded. The first item of the relative - path must not start with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of - the container: only resources limits - and requests (limits.cpu, limits.memory, - requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required - for volumes, optional for env - vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output - format of the exposed resources, - defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource - to select' - type: string - required: - - resource - type: object - required: - - path - type: object - type: array - type: object - secret: - description: information about the secret data - to project - properties: - items: - description: If unspecified, each key-value - pair in the Data field of the referenced - Secret will be projected into the volume - as a file whose name is the key and content - is the value. If specified, the listed keys - will be projected into the specified paths, - and unlisted keys will not be present. If - a key is specified which is not present - in the Secret, the volume setup will error - unless it is marked optional. Paths must - be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path - within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain - the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or - its key must be defined - type: boolean - type: object - serviceAccountToken: - description: information about the serviceAccountToken - data to project - properties: - audience: - description: Audience is the intended audience - of the token. A recipient of a token must - identify itself with an identifier specified - in the audience of the token, and otherwise - should reject the token. The audience defaults - to the identifier of the apiserver. - type: string - expirationSeconds: - description: ExpirationSeconds is the requested - duration of validity of the service account - token. As the token approaches expiration, - the kubelet volume plugin will proactively - rotate the service account token. The kubelet - will start trying to rotate the token if - the token is older than 80 percent of its - time to live or if the token is older than - 24 hours.Defaults to 1 hour and must be - at least 10 minutes. - format: int64 - type: integer - path: - description: Path is the path relative to - the mount point of the file to project the - token into. - type: string - required: - - path - type: object - type: object - type: array - type: object - quobyte: - description: Quobyte represents a Quobyte mount on the host - that shares a pod's lifetime - properties: - group: - description: Group to map volume access to Default is - no group - type: string - readOnly: - description: ReadOnly here will force the Quobyte volume - to be mounted with read-only permissions. Defaults - to false. - type: boolean - registry: - description: Registry represents a single or multiple - Quobyte Registry services specified as a string as - host:port pair (multiple entries are separated with - commas) which acts as the central registry for volumes - type: string - tenant: - description: Tenant owning the given Quobyte volume - in the Backend Used with dynamically provisioned Quobyte - volumes, value is set by the plugin - type: string - user: - description: User to map volume access to Defaults to - serivceaccount user - type: string - volume: - description: Volume is a string that references an already - created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: 'RBD represents a Rados Block Device mount - on the host that shares a pod''s lifetime. More info: - https://examples.k8s.io/volumes/rbd/README.md' - properties: - fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - keyring: - description: 'Keyring is the path to key ring for RBDUser. - Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - items: - type: string - type: array - pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - readOnly: - description: 'ReadOnly here will force the ReadOnly - setting in VolumeMounts. Defaults to false. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: boolean - secretRef: - description: 'SecretRef is name of the authentication - secret for RBDUser. If provided overrides keyring. - Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - required: - - image - - monitors - type: object - scaleIO: - description: ScaleIO represents a ScaleIO persistent volume - attached and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". - type: string - gateway: - description: The host address of the ScaleIO API Gateway. - type: string - protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef references to the secret for - ScaleIO user and other sensitive information. If this - is not provided, Login operation will fail. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - sslEnabled: - description: Flag to enable/disable SSL communication - with Gateway, default false - type: boolean - storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. - type: string - storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. - type: string - system: - description: The name of the storage system as configured - in ScaleIO. - type: string - volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: 'Secret represents a secret that should populate - this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - properties: - defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' - format: int32 - type: integer - items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. - items: - description: Maps a string key to a path within a - volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' - format: int32 - type: integer - path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. - type: string - required: - - key - - path - type: object - type: array - optional: - description: Specify whether the Secret or its keys - must be defined - type: boolean - secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - type: object - storageos: - description: StorageOS represents a StorageOS volume attached - and mounted on Kubernetes nodes. - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: SecretRef specifies the secret to use for - obtaining the StorageOS API credentials. If not specified, - default values will be attempted. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - type: object - volumeName: - description: VolumeName is the human-readable name of - the StorageOS volume. Volume names are only unique - within a namespace. - type: string - volumeNamespace: - description: VolumeNamespace specifies the scope of - the volume within StorageOS. If no namespace is specified - then the Pod's namespace will be used. This allows - the Kubernetes name scoping to be mirrored within - StorageOS for tighter integration. Set VolumeName - to any name to override the default behaviour. Set - to "default" if you are not using namespaces within - StorageOS. Namespaces that do not pre-exist within - StorageOS will be created. - type: string - type: object - vsphereVolume: - description: VsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine - properties: - fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. - type: string - storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. - type: string - storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. - type: string - volumePath: - description: Path that identifies vSphere volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - type: object - repositoryCredentials: - description: RepositoryCredentials are the Git pull credentials to - configure Argo CD with upon creation of the cluster. - type: string - resourceActions: - description: ResourceActions customizes resource action behavior. - items: - description: Resource Customization for custom action - properties: - action: - type: string - group: - type: string - kind: - type: string - type: object - type: array resourceCustomizations: description: 'Deprecated field. Support dropped in v1beta1 version. ResourceCustomizations customizes resource behavior. Keys are in diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 2787d999d..b19eb6938 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -229,30 +229,30 @@ func (r *ArgoCDReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *ArgoCDReconciler) reconcileControllers() error { // core components, return reconciliation errors - if err := r.SecretController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile secret controller") - return err - } + // if err := r.SecretController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile secret controller") + // return err + // } - if err := r.ConfigMapController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile configmap controller") - return err - } + // if err := r.ConfigMapController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile configmap controller") + // return err + // } - if err := r.AppController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile application controller") - return err - } + // if err := r.AppController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile application controller") + // return err + // } - if err := r.ServerController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile server") - return err - } + // if err := r.ServerController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile server") + // return err + // } - if err := r.RedisController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile redis controller") - return err - } + // if err := r.RedisController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile redis controller") + // return err + // } if err := r.ReposerverController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile reposerver controller") @@ -260,25 +260,25 @@ func (r *ArgoCDReconciler) reconcileControllers() error { } // non-core components, don't return reconciliation errors - if r.Instance.Spec.ApplicationSet != nil { - if err := r.AppsetController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile applicationset controller") - } - } else { - if err := r.AppsetController.DeleteResources(); err != nil { - r.Logger.Error(err, "failed to delete applicationset resources") - } - } + // if r.Instance.Spec.ApplicationSet != nil { + // if err := r.AppsetController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile applicationset controller") + // } + // } else { + // if err := r.AppsetController.DeleteResources(); err != nil { + // r.Logger.Error(err, "failed to delete applicationset resources") + // } + // } - if r.Instance.Spec.Notifications.Enabled { - if err := r.NotificationsController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile notifications controller") - } - } else { - if err := r.NotificationsController.DeleteResources(); err != nil { - r.Logger.Error(err, "failed to delete notifications resources") - } - } + // if r.Instance.Spec.Notifications.Enabled { + // if err := r.NotificationsController.Reconcile(); err != nil { + // r.Logger.Error(err, "failed to reconcile notifications controller") + // } + // } else { + // if err := r.NotificationsController.DeleteResources(); err != nil { + // r.Logger.Error(err, "failed to delete notifications resources") + // } + // } if err := r.SSOController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile SSO controller") diff --git a/controllers/argocd/redis/util.go b/controllers/argocd/redis/util.go index 079802c11..f987beeb7 100644 --- a/controllers/argocd/redis/util.go +++ b/controllers/argocd/redis/util.go @@ -27,12 +27,10 @@ func GetRedisHAProxyAddress(namespace string) string { } func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, error) { - var tlsSecretObj corev1.Secret tlsSecretName := types.NamespacedName{Namespace: instanceNamespace, Name: common.ArgoCDRedisServerTLSSecretName} - err := client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) - if err != nil { + var tlsSecretObj corev1.Secret + if err := client.Get(context.TODO(), tlsSecretName, &tlsSecretObj); err != nil { if !errors.IsNotFound(err) { - // Error reading the secret return false, err } return false, nil @@ -47,11 +45,8 @@ func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, er if argocdcommon.IsOwnerOfInterest(secretOwner) { key := cntrlClient.ObjectKey{Name: secretOwner.Name, Namespace: tlsSecretObj.GetNamespace()} svc := &corev1.Service{} - // Get the owning object of the secret - err := client.Get(context.TODO(), key, svc) - if err != nil { - // log.Error(err, fmt.Sprintf("could not get owner of secret %s", tlsSecretObj.GetName())) + if err := client.Get(context.TODO(), key, svc); err != nil { return false, err } diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 9e01efb81..3a35c374b 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -55,7 +55,7 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { existingDeployment, err := workloads.GetDeployment(desiredDeployment.Name, desiredDeployment.Namespace, rsr.Client) if err != nil { if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileDeployment: failed to retrieve deployment", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + rsr.Logger.Error(err, "reconcileDeployment: failed to retrieve deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err } diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go new file mode 100644 index 000000000..c64dfdbeb --- /dev/null +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -0,0 +1,36 @@ +package reposerver + +import ( + "testing" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, RepoServerControllerComponent) + +func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoServerReconciler { + s := scheme.Scheme + + assert.NoError(t, monitoringv1.AddToScheme(s)) + assert.NoError(t, argoproj.AddToScheme(s)) + + cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() + logger := ctrl.Log.WithName(RepoServerControllerComponent) + + return &RepoServerReconciler{ + Client: cl, + Scheme: s, + Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { + a.Spec.Repo = argoproj.ArgoCDRepoSpec{} + }), + Logger: logger, + } +} diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index b66a86a84..59c3337e4 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -50,7 +50,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { existingService, err := networking.GetService(desiredService.Name, desiredService.Namespace, rsr.Client) if err != nil { if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileService: failed to retrieve service", "name", existingService.Name, "namespace", existingService.Namespace) + rsr.Logger.Error(err, "reconcileService: failed to retrieve service", "name", desiredService.Name, "namespace", desiredService.Namespace) return err } diff --git a/controllers/argocd/reposerver/service_test.go b/controllers/argocd/reposerver/service_test.go new file mode 100644 index 000000000..59eed7332 --- /dev/null +++ b/controllers/argocd/reposerver/service_test.go @@ -0,0 +1,81 @@ +package reposerver + +import ( + "context" + "testing" + + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestRepoServerReconciler_reconcileTLSService(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + sa := argocdcommon.MakeTestServiceAccount() + resourceName = argocdcommon.TestArgoCDName + + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "create a Service", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns, sa) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nr := tt.setupClient() + err := nr.reconcileService() + if (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + currentService := &corev1.Service{} + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) + if err != nil { + t.Fatalf("Could not get current Service: %v", err) + } + assert.Equal(t, GetServiceSpec().Ports, currentService.Spec.Ports) + }) + } +} + +func TestRepoServerReconciler_DeleteService(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + sa := argocdcommon.MakeTestServiceAccount() + resourceName = argocdcommon.TestArgoCDName + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "successful delete", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns, sa) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nr := tt.setupClient() + if err := nr.deleteService(resourceName, ns.Name); (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + }) + } +} diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index afac28674..1422fe92e 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -41,10 +41,10 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { return err } - existingServiceMonitor, err := monitoring.GetServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace, rsr.Client) + _, err = monitoring.GetServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace, rsr.Client) if err != nil { if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to retrieve serviceMonitor", "name", existingServiceMonitor.Name, "namespace", existingServiceMonitor.Namespace) + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to retrieve serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) return err } diff --git a/controllers/argocd/reposerver/tlssecret.go b/controllers/argocd/reposerver/tlssecret.go index d1f3b2d17..388bee703 100644 --- a/controllers/argocd/reposerver/tlssecret.go +++ b/controllers/argocd/reposerver/tlssecret.go @@ -1,6 +1,7 @@ package reposerver import ( + "context" "crypto/sha256" "fmt" @@ -8,51 +9,32 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/appcontroller" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/cluster" - "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/workloads" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func (rsr *RepoServerReconciler) reconcileTLSSecret() error { var sha256sum string rsr.Logger.Info("reconciling TLS secrets") - secretRequest := workloads.SecretRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: RepoServerTLSSecretName, - Namespace: rsr.Instance.Namespace, - Labels: resourceLabels, - }, - - Client: rsr.Client, - Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, - } - - desiredSecret, err := workloads.RequestSecret(secretRequest) - if err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to request secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) - return err - } - namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) if err != nil { rsr.Logger.Error(err, "reconcileSecret: failed to retrieve namespace", "name", rsr.Instance.Namespace) return err } if namespace.DeletionTimestamp != nil { - if err := rsr.deleteTLSSecret(desiredSecret.Namespace); err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + if err := rsr.deleteTLSSecret(rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) } return err } - existingSecret, err := workloads.GetSecret(desiredSecret.Name, desiredSecret.Namespace, rsr.Client) + existingSecret, err := workloads.GetSecret(RepoServerTLSSecretName, rsr.Instance.Namespace, rsr.Client) if err != nil { if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", existingSecret.Name, "namespace", existingSecret.Namespace) + rsr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) return err } } else if existingSecret.Type != corev1.SecretTypeTLS { @@ -70,9 +52,10 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { if rsr.Instance.Status.RepoTLSChecksum != sha256sum { rsr.Instance.Status.RepoTLSChecksum = sha256sum - err = workloads.UpdateSecret(desiredSecret, rsr.Client) + err = rsr.Client.Status().Update(context.TODO(), rsr.Instance) + // err = workloads.UpdateSecret(desiredSecret, rsr.Client) if err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to update secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + rsr.Logger.Error(err, "reconcileSecret: failed to update status", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) return err } @@ -89,7 +72,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } } - rsr.Logger.V(0).Info("reconcileSecret: TLS secret updated", "name", RepoServerTLSSecretName, "namespace", desiredSecret.Namespace) + rsr.Logger.V(0).Info("reconcileSecret: argocd client status updated", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) return nil } diff --git a/controllers/argocd/reposerver/tlssecret_test.go b/controllers/argocd/reposerver/tlssecret_test.go new file mode 100644 index 000000000..fd8aaa369 --- /dev/null +++ b/controllers/argocd/reposerver/tlssecret_test.go @@ -0,0 +1,79 @@ +package reposerver + +import ( + "context" + "testing" + + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/stretchr/testify/assert" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestRepoServerReconciler_reconcileSecret(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + resourceLabels = testExpectedLabels + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "create a secret", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nr := tt.setupClient() + err := nr.reconcileTLSSecret() + if (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + + currentSecret := &corev1.Secret{} + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: RepoServerTLSSecretName, Namespace: argocdcommon.TestNamespace}, currentSecret) + if err != nil { + t.Fatalf("Could not get current Secret: %v", err) + } + assert.Equal(t, testExpectedLabels, currentSecret.ObjectMeta.Labels) + }) + } +} + +func TestRepoServerReconciler_DeleteSecret(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "successful delete", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nr := tt.setupClient() + if err := nr.deleteTLSSecret(ns.Name); (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + }) + } +} From 26c9f09b711970ca2e4ddf5730e041976b8b2474 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Fri, 6 Oct 2023 18:40:02 -0400 Subject: [PATCH 27/94] Added unit tests(except for tlssecret) Signed-off-by: Yi Cai --- .../argocd/applicationset/deployment.go | 3 + .../argocd/notifications/deployment.go | 3 + controllers/argocd/reposerver/deployment.go | 31 ++++-- .../argocd/reposerver/deployment_test.go | 94 +++++++++++++++++++ controllers/argocd/reposerver/reposerver.go | 17 +++- .../argocd/reposerver/reposerver_test.go | 6 +- .../argocd/reposerver/servicemonitor.go | 14 +++ .../argocd/reposerver/servicemonitor_test.go | 83 ++++++++++++++++ .../argocd/reposerver/tlssecret_test.go | 1 + 9 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 controllers/argocd/reposerver/deployment_test.go create mode 100644 controllers/argocd/reposerver/servicemonitor_test.go diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index d1f7b7e49..8fd64282c 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -70,6 +70,9 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { }{ {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, func() { + if existingDeployment.Spec.Template.ObjectMeta.Labels == nil { + existingDeployment.Spec.Template.ObjectMeta.Labels = map[string]string{} + } existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index a855195b3..09dd0f498 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -70,6 +70,9 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { }{ {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, func() { + if existingDeployment.Spec.Template.ObjectMeta.Labels == nil { + existingDeployment.Spec.Template.ObjectMeta.Labels = map[string]string{} + } existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 3a35c374b..3a3192545 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -78,20 +78,23 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { }{ {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, func() { + if existingDeployment.Spec.Template.ObjectMeta.Labels == nil { + existingDeployment.Spec.Template.ObjectMeta.Labels = map[string]string{} + } existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, {&existingDeployment.Spec.Template.Spec.NodeSelector, &desiredDeployment.Spec.Template.Spec.NodeSelector, nil}, {&existingDeployment.Spec.Template.Spec.Tolerations, &desiredDeployment.Spec.Template.Spec.Tolerations, nil}, - {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, // - {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, // - {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, // - {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, // - {&existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, &desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, nil}, // - {&existingDeployment.Spec.Template.Spec.InitContainers, &desiredDeployment.Spec.Template.Spec.InitContainers, nil}, // - {&existingDeployment.Spec.Template.Spec.AutomountServiceAccountToken, &desiredDeployment.Spec.Template.Spec.AutomountServiceAccountToken, nil}, // - {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, // - {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, // + {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, + {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, + {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, + {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, + {&existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, &desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, nil}, + {&existingDeployment.Spec.Template.Spec.InitContainers, &desiredDeployment.Spec.Template.Spec.InitContainers, nil}, + {&existingDeployment.Spec.Template.Spec.AutomountServiceAccountToken, &desiredDeployment.Spec.Template.Spec.AutomountServiceAccountToken, nil}, + {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, + {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, } for _, field := range fieldsToCompare { @@ -146,6 +149,16 @@ func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *apps RunAsNonRoot: util.BoolPtr(true), }, AutomountServiceAccountToken: &automountToken, + NodeSelector: common.DefaultNodeSelector(), + } + + if rsr.Instance.Spec.NodePlacement != nil { + podSpec.NodeSelector = util.AppendStringMap(podSpec.NodeSelector, rsr.Instance.Spec.NodePlacement.NodeSelector) + podSpec.Tolerations = rsr.Instance.Spec.NodePlacement.Tolerations + } + + if rsr.Instance.Spec.Repo.ServiceAccount != "" { + podSpec.ServiceAccountName = rsr.Instance.Spec.Repo.ServiceAccount } deploymentSpec := appsv1.DeploymentSpec{ diff --git a/controllers/argocd/reposerver/deployment_test.go b/controllers/argocd/reposerver/deployment_test.go new file mode 100644 index 000000000..a6462624c --- /dev/null +++ b/controllers/argocd/reposerver/deployment_test.go @@ -0,0 +1,94 @@ +package reposerver + +import ( + "context" + "testing" + + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/stretchr/testify/assert" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/types" +) + +func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { + resourceName = argocdcommon.TestArgoCDName + resourceLabels = testExpectedLabels + ns := argocdcommon.MakeTestNamespace() + asr := makeTestRepoServerReconciler(t, ns) + + existingDeployment := asr.getDesiredDeployment(false) // todo + + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "create a deployment", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns) + }, + wantErr: false, + }, + { + name: "update a deployment", + setupClient: func() *RepoServerReconciler { + outdatedDeployment := existingDeployment + outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" + return makeTestRepoServerReconciler(t, outdatedDeployment, ns) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + asr := tt.setupClient() + err := asr.reconcileDeployment() + if (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + + updatedDeployment := &appsv1.Deployment{} + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: argocdcommon.TestNamespace}, updatedDeployment) + if err != nil { + t.Fatalf("Could not get updated Deployment: %v", err) + } + assert.Equal(t, testServiceAccount, updatedDeployment.Spec.Template.Spec.ServiceAccountName) + }) + } +} + +func TestRepoServerReconciler_DeleteDeployment(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + resourceName = argocdcommon.TestArgoCDName + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "successful delete", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + asr := tt.setupClient() + if err := asr.deleteDeployment(resourceName, ns.Name); (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + }) + } +} diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index e460b8890..ecc71844b 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -32,9 +32,16 @@ func (rsr *RepoServerReconciler) Reconcile() error { return err } - if err := rsr.reconcileServiceMonitor(); err != nil { - rsr.Logger.Info("reconciling repo server serviceMonitor") - return err + if rsr.Instance.Spec.Prometheus.Enabled { + if err := rsr.reconcileServiceMonitor(); err != nil { + rsr.Logger.Info("reconciling repo server serviceMonitor") + return err + } + } else { + if err := rsr.deleteServiceMonitor(resourceName, rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "DeleteResources: failed to delete serviceMonitor") + return err + } } if err := rsr.reconcileTLSSecret(); err != nil { @@ -64,8 +71,8 @@ func (rsr *RepoServerReconciler) DeleteResources() error { deletionError = err } - if err := rsr.deleteService(resourceName, rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "DeleteResources: failed to delete service") + if err := rsr.deleteServiceMonitor(resourceName, rsr.Instance.Namespace); err != nil { + rsr.Logger.Error(err, "DeleteResources: failed to delete serviceMonitor") deletionError = err } diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index c64dfdbeb..010a28021 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -16,6 +16,8 @@ import ( var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, RepoServerControllerComponent) +const testServiceAccount = "test-service-account" + func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoServerReconciler { s := scheme.Scheme @@ -29,7 +31,9 @@ func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoSer Client: cl, Scheme: s, Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Repo = argoproj.ArgoCDRepoSpec{} + a.Spec.Repo = argoproj.ArgoCDRepoSpec{ + ServiceAccount: testServiceAccount, + } }), Logger: logger, } diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index 1422fe92e..f87db24ec 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -1,9 +1,11 @@ package reposerver import ( + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/monitoring" "github.com/argoproj-labs/argocd-operator/pkg/util" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -21,6 +23,18 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { Labels: resourceLabels, Annotations: rsr.Instance.Annotations, }, + Spec: monitoringv1.ServiceMonitorSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.AppK8sKeyName: util.GenerateResourceName(rsr.Instance.Name, RepoServerControllerComponent), + }, + }, + Endpoints: []monitoringv1.Endpoint{ + { + Port: common.ArgoCDMetrics, + }, + }, + }, } desiredServiceMonitor, err := monitoring.RequestServiceMonitor(serviceMonitorRequest) diff --git a/controllers/argocd/reposerver/servicemonitor_test.go b/controllers/argocd/reposerver/servicemonitor_test.go new file mode 100644 index 000000000..73d993d9f --- /dev/null +++ b/controllers/argocd/reposerver/servicemonitor_test.go @@ -0,0 +1,83 @@ +package reposerver + +import ( + "context" + "testing" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/util" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/types" +) + +func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + sa := argocdcommon.MakeTestServiceAccount() + resourceName = argocdcommon.TestArgoCDName + + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "create a ServiceMonitor", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns, sa) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rsr := tt.setupClient() + err := rsr.reconcileServiceMonitor() + if (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + currentService := &monitoringv1.ServiceMonitor{} + err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: util.GenerateResourceName(rsr.Instance.Name, RepoServerMetrics), Namespace: argocdcommon.TestNamespace}, currentService) + if err != nil { + t.Fatalf("Could not get current Service: %v", err) + } + assert.Equal(t, common.ArgoCDMetrics, currentService.Spec.Endpoints[0].Port) + }) + } +} + +func TestRepoServerReconciler_DeleteServiceMonitor(t *testing.T) { + ns := argocdcommon.MakeTestNamespace() + sa := argocdcommon.MakeTestServiceAccount() + resourceName = argocdcommon.TestArgoCDName + tests := []struct { + name string + setupClient func() *RepoServerReconciler + wantErr bool + }{ + { + name: "successful delete", + setupClient: func() *RepoServerReconciler { + return makeTestRepoServerReconciler(t, ns, sa) + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nr := tt.setupClient() + if err := nr.deleteServiceMonitor(resourceName, ns.Name); (err != nil) != tt.wantErr { + if tt.wantErr { + t.Errorf("Expected error but did not get one") + } else { + t.Errorf("Unexpected error: %v", err) + } + } + }) + } +} diff --git a/controllers/argocd/reposerver/tlssecret_test.go b/controllers/argocd/reposerver/tlssecret_test.go index fd8aaa369..de6f481fd 100644 --- a/controllers/argocd/reposerver/tlssecret_test.go +++ b/controllers/argocd/reposerver/tlssecret_test.go @@ -12,6 +12,7 @@ import ( ) func TestRepoServerReconciler_reconcileSecret(t *testing.T) { + // TODO: Add test cases for updating status from secret change ns := argocdcommon.MakeTestNamespace() resourceLabels = testExpectedLabels tests := []struct { From 6b3fbb6a12aaa8f5759bf8e1f8cf02260ebb2f41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:19:08 +0530 Subject: [PATCH 28/94] chore(deps): bump golang.org/x/net from 0.11.0 to 0.17.0 (#1019) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.11.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.11.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 471d24fa6..adb4eb2a3 100644 --- a/go.mod +++ b/go.mod @@ -67,12 +67,12 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.10.0 // indirect - golang.org/x/net v0.11.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.9.0 // indirect - golang.org/x/sys v0.9.0 // indirect - golang.org/x/term v0.9.0 // indirect - golang.org/x/text v0.10.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 5e45feb61..841ce8cbf 100644 --- a/go.sum +++ b/go.sum @@ -1271,8 +1271,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1373,8 +1373,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1502,14 +1502,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1519,8 +1519,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 9798a355fbf9e681f623ea1da305e1f3b9f36ae8 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Mon, 16 Oct 2023 15:44:20 -0400 Subject: [PATCH 29/94] Addressed comments Signed-off-by: Yi Cai --- common/values.go | 1 + controllers/argocd/argocdcommon/argohelper.go | 15 ++++---- .../reposerver/{tlssecret.go => secret.go} | 14 +++++--- .../{tlssecret_test.go => secret_test.go} | 0 pkg/util/time.go | 11 ++++++ pkg/workloads/deployment.go | 34 ++----------------- pkg/workloads/statefulset.go | 7 ++-- 7 files changed, 34 insertions(+), 48 deletions(-) rename controllers/argocd/reposerver/{tlssecret.go => secret.go} (83%) rename controllers/argocd/reposerver/{tlssecret_test.go => secret_test.go} (100%) create mode 100644 pkg/util/time.go diff --git a/common/values.go b/common/values.go index 269e2dc2f..e19e85730 100644 --- a/common/values.go +++ b/common/values.go @@ -95,6 +95,7 @@ const ( SecretKind = "Secret" ServiceKind = "Service" ServiceAccountKind = "ServiceAccount" + StatefulSetKind = "StatefulSet" ) // Commnds diff --git a/controllers/argocd/argocdcommon/argohelper.go b/controllers/argocd/argocdcommon/argohelper.go index 84fb8887e..e73ed783f 100644 --- a/controllers/argocd/argocdcommon/argohelper.go +++ b/controllers/argocd/argocdcommon/argohelper.go @@ -9,7 +9,6 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" - appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -62,13 +61,13 @@ func IsOwnerOfInterest(owner metav1.OwnerReference) bool { // TriggerRollout will trigger a rollout of a Kubernetes resource specified as // obj. It currently supports Deployment and StatefulSet resources. -func TriggerRollout(client cntrlClient.Client, obj interface{}, key string) error { - switch res := obj.(type) { - case *appsv1.Deployment: - return workloads.TriggerDeploymentRollout(client, res, key) - case *appsv1.StatefulSet: - return workloads.TriggerStatefulSetRollout(client, res, key) +func TriggerRollout(client cntrlClient.Client, name, namespace, resType string, opt func(name string, namespace string)) error { + switch resType { + case common.DeploymentKind: + return workloads.TriggerDeploymentRollout(client, name, namespace, opt) + case common.StatefulSetKind: + return workloads.TriggerStatefulSetRollout(client, name, namespace, opt) default: - return fmt.Errorf("resource of unknown type %T, cannot trigger rollout", res) + return fmt.Errorf("resource of unknown type %T, cannot trigger rollout", resType) } } diff --git a/controllers/argocd/reposerver/tlssecret.go b/controllers/argocd/reposerver/secret.go similarity index 83% rename from controllers/argocd/reposerver/tlssecret.go rename to controllers/argocd/reposerver/secret.go index 388bee703..00a47ea9d 100644 --- a/controllers/argocd/reposerver/tlssecret.go +++ b/controllers/argocd/reposerver/secret.go @@ -9,6 +9,7 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/appcontroller" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/cluster" + "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" corev1 "k8s.io/api/core/v1" @@ -62,11 +63,14 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { // Trigger rollout of API components components := []string{common.Server, RepoServerControllerComponent, appcontroller.ArgoCDApplicationControllerComponent} for _, component := range components { - depl, err := workloads.CreateDeploymentWithSuffix(component, component, rsr.Instance) - if err != nil { - return err - } - err = argocdcommon.TriggerRollout(rsr.Client, depl, common.ArgoCDRepoTLSCertChangedKey) + name := util.NameWithSuffix(rsr.Instance.Name, component) + err = argocdcommon.TriggerRollout(rsr.Client, name, rsr.Instance.Namespace, common.DeploymentKind, func(name string, namespace string) { + deployment, err := workloads.GetDeployment(name, namespace, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "reconcileSecret: failed to retrieve deployment", "name", name, "namespace", namespace) + } + deployment.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() + }) if err != nil { return err } diff --git a/controllers/argocd/reposerver/tlssecret_test.go b/controllers/argocd/reposerver/secret_test.go similarity index 100% rename from controllers/argocd/reposerver/tlssecret_test.go rename to controllers/argocd/reposerver/secret_test.go diff --git a/pkg/util/time.go b/pkg/util/time.go new file mode 100644 index 000000000..34b6612fc --- /dev/null +++ b/pkg/util/time.go @@ -0,0 +1,11 @@ +package util + +import ( + "fmt" + "time" +) + +// nowNano returns a string with the current UTC time as epoch in nanoseconds +func NowNano() string { + return fmt.Sprintf("%d", time.Now().UTC().UnixNano()) +} diff --git a/pkg/workloads/deployment.go b/pkg/workloads/deployment.go index a9c337008..7033410d0 100644 --- a/pkg/workloads/deployment.go +++ b/pkg/workloads/deployment.go @@ -3,12 +3,8 @@ package workloads import ( "context" "fmt" - "time" - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" - util "github.com/argoproj-labs/argocd-operator/pkg/util" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -106,28 +102,9 @@ func RequestDeployment(request DeploymentRequest) (*appsv1.Deployment, error) { return deployment, nil } -func CreateDeploymentWithSuffix(suffix string, component string, cr *argoproj.ArgoCD) (*appsv1.Deployment, error) { - lbls := cr.Labels - lbls[common.AppK8sKeyComponent] = component - deploymentRequest := DeploymentRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: util.NameWithSuffix(cr.Name, suffix), - Namespace: cr.Namespace, - Labels: lbls, - }, - } - - deployment, err := RequestDeployment(deploymentRequest) - if err != nil { - return nil, err - } - - return deployment, nil -} - // TriggerDeploymentRollout will update the label with the given key to trigger a new rollout of the Deployment. -func TriggerDeploymentRollout(client cntrlClient.Client, deployment *appsv1.Deployment, key string) error { - currentDeployment, err := GetDeployment(deployment.Name, deployment.Namespace, client) +func TriggerDeploymentRollout(client cntrlClient.Client, name, namespace string, updateChangedTime func(name, namespace string)) error { + currentDeployment, err := GetDeployment(name, namespace, client) if err != nil { if !errors.IsNotFound(err) { return err @@ -135,11 +112,6 @@ func TriggerDeploymentRollout(client cntrlClient.Client, deployment *appsv1.Depl return nil } - currentDeployment.Spec.Template.ObjectMeta.Labels[key] = NowNano() + updateChangedTime(currentDeployment.Name, currentDeployment.Namespace) return UpdateDeployment(currentDeployment, client) } - -// nowNano returns a string with the current UTC time as epoch in nanoseconds -func NowNano() string { - return fmt.Sprintf("%d", time.Now().UTC().UnixNano()) -} diff --git a/pkg/workloads/statefulset.go b/pkg/workloads/statefulset.go index 613d39ff7..b7d16e18e 100644 --- a/pkg/workloads/statefulset.go +++ b/pkg/workloads/statefulset.go @@ -102,15 +102,14 @@ func RequestStatefulSet(request StatefulSetRequest) (*appsv1.StatefulSet, error) } // TriggerStatefulSetRollout will update the label with the given key to trigger a new rollout of the StatefulSet. -func TriggerStatefulSetRollout(client cntrlClient.Client, sts *appsv1.StatefulSet, key string) error { - currentStatefulSet, err := GetStatefulSet(sts.Name, sts.Namespace, client) +func TriggerStatefulSetRollout(client cntrlClient.Client, name, namespace string, updateChangedTime func(name, namespace string)) error { + currentStatefulSet, err := GetStatefulSet(name, namespace, client) if err != nil { if !errors.IsNotFound(err) { return err } return nil } - - currentStatefulSet.Spec.Template.ObjectMeta.Labels[key] = NowNano() + updateChangedTime(currentStatefulSet.Name, currentStatefulSet.Namespace) return UpdateStatefulSet(currentStatefulSet, client) } From 5a2e6c40e533bcfd01698e6efe1b4486c0a88c5a Mon Sep 17 00:00:00 2001 From: Raghavi Date: Thu, 19 Oct 2023 12:20:10 +0530 Subject: [PATCH 30/94] Add labelSelector option to filter the ArgoCD instances for reconciliation (#961) * Added labelselector string to map conversion Signed-off-by: Raghavi Shirur * Changed data-type for labelSelector to parse string Signed-off-by: Raghavi Shirur * Added code to reconcile selected ArgoCD instances based on label selector Signed-off-by: Raghavi Shirur * remove comments Signed-off-by: Raghavi Shirur * Updated argoCD label fetch, renamed env var Signed-off-by: Raghavi Shirur * Updated unit test and yaml Signed-off-by: Raghavi Shirur * Updated unit test Signed-off-by: Raghavi Shirur * Fix yaml env ValueFrom field Signed-off-by: Raghavi Shirur * Added comments and labelSelector check in main.go Signed-off-by: Raghavi Shirur * removed label-selector option from manifest Signed-off-by: Raghavi Shirur * updated label-selector format in manifests Signed-off-by: Raghavi Shirur * added label selector logs Signed-off-by: Raghavi Shirur * go mod tidy Signed-off-by: Raghavi Shirur * added e2e tests for label-selector Signed-off-by: Raghavi Shirur * restructured kuttl files and added operator patch file Signed-off-by: Raghavi Shirur * go mod tidy Signed-off-by: Raghavi Shirur * corrected kuttl tests for cm failure Signed-off-by: Raghavi Shirur * Added documentation for Environment Variable ARGOCD_LABEL_SELECTOR Signed-off-by: Raghavi Shirur * cleanup Signed-off-by: Raghavi Shirur * improved unit tests and some minor changes Signed-off-by: Raghavi Shirur * kuttl rerun Signed-off-by: Raghavi Shirur * removed env var Signed-off-by: Raghavi Shirur * misc modifications Signed-off-by: Raghavi Shirur * argocd-operator csv correction Signed-off-by: Raghavi Shirur * fix bundle error Signed-off-by: Raghavi Shirur * fix bundle error Signed-off-by: Raghavi Shirur * fix manifests build Signed-off-by: Raghavi Shirur Signed-off-by: Ishita Sequeira Signed-off-by: Raghavi Shirur * Added more unit test cases Signed-off-by: Raghavi Shirur * rebase Signed-off-by: Raghavi Shirur * removed excess reconcilers Signed-off-by: Raghavi Shirur * minor fix Signed-off-by: Raghavi Shirur * removed extraneous test case and cleaned manager.yaml Signed-off-by: Raghavi Shirur * cleaned manager.yaml Signed-off-by: Raghavi Shirur * fix make bundle issue Signed-off-by: Raghavi Shirur * fix make bundle issue Signed-off-by: Raghavi Shirur --------- Signed-off-by: Raghavi Shirur Signed-off-by: Ishita Sequeira Co-authored-by: ishitasequeira --- common/defaults.go | 3 + common/keys.go | 3 + controllers/argocd/argocd_controller.go | 15 +++ controllers/argocd/argocd_controller_test.go | 101 +++++++++++++++++++ docs/usage/environment_variables.md | 1 + go.mod | 2 + go.sum | 45 +++++++++ main.go | 16 ++- 8 files changed, 184 insertions(+), 2 deletions(-) diff --git a/common/defaults.go b/common/defaults.go index 2912428e8..e74b3807d 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -178,6 +178,9 @@ const ( // ArgoCDKeycloakImage is the default Keycloak Image used for the non-openshift platforms when not specified. ArgoCDKeycloakImage = "quay.io/keycloak/keycloak" + // ArgoCDDefaultLabelSelector is the default Label Selector which will reconcile all ArgoCD instances. + ArgoCDDefaultLabelSelector = "" + // ArgoCDKeycloakVersion is the default Keycloak version used for the non-openshift platform when not specified. // Version: 15.0.2 ArgoCDKeycloakVersion = "sha256:64fb81886fde61dee55091e6033481fa5ccdac62ae30a4fd29b54eb5e97df6a9" diff --git a/common/keys.go b/common/keys.go index 01db690f7..b64ac3838 100644 --- a/common/keys.go +++ b/common/keys.go @@ -228,4 +228,7 @@ const ( // ArgoCDDexSecretKey is used to reference Dex secret from Argo CD secret into Argo CD configmap ArgoCDDexSecretKey = "oidc.dex.clientSecret" + + // Label Selector is an env variable for ArgoCD instance reconcilliation. + ArgoCDLabelSelectorKey = "ARGOCD_LABEL_SELECTOR" ) diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 85cd17e48..096649c02 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -27,6 +27,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" @@ -46,6 +47,8 @@ type ReconcileArgoCD struct { ManagedNamespaces *corev1.NamespaceList // Stores a list of SourceNamespaces as values ManagedSourceNamespaces map[string]string + // Stores label selector used to reconcile a subset of ArgoCD + LabelSelector string } var log = logr.Log.WithName("controller_argocd") @@ -105,6 +108,18 @@ func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) ( return reconcile.Result{}, err } + // Fetch labelSelector from r.LabelSelector (command-line option) + labelSelector, err := labels.Parse(r.LabelSelector) + if err != nil { + reqLogger.Info(fmt.Sprintf("error parsing the labelSelector '%s'.", labelSelector)) + return reconcile.Result{}, err + } + // Match the value of labelSelector from ReconcileArgoCD to labels from the argocd instance + if !labelSelector.Matches(labels.Set(argocd.Labels)) { + reqLogger.Info(fmt.Sprintf("the ArgoCD instance '%s' does not match the label selector '%s' and skipping for reconciliation", request.NamespacedName, r.LabelSelector)) + return reconcile.Result{}, fmt.Errorf("Error: failed to reconcile ArgoCD instance: '%s'", request.NamespacedName) + } + newPhase := argocd.Status.Phase // If we discover a new Argo CD instance in a previously un-seen namespace // we add it to the map and increment active instance count by phase diff --git a/controllers/argocd/argocd_controller_test.go b/controllers/argocd/argocd_controller_test.go index 0cad71c79..292bcf361 100644 --- a/controllers/argocd/argocd_controller_test.go +++ b/controllers/argocd/argocd_controller_test.go @@ -102,6 +102,107 @@ func TestReconcileArgoCD_Reconcile(t *testing.T) { } } +func TestReconcileArgoCD_LabelSelector(t *testing.T) { + logf.SetLogger(ZapLogger(true)) + //ctx := context.Background() + a := makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Name = "argo-test-1" + ac.Labels = map[string]string{"foo": "bar"} + }) + b := makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Name = "argo-test-2" + ac.Labels = map[string]string{"testfoo": "testbar"} + }) + c := makeTestArgoCD(func(ac *argoproj.ArgoCD) { + ac.Name = "argo-test-3" + }) + rt := makeTestReconciler(t, a, b, c) + assert.NoError(t, createNamespace(rt, a.Namespace, "")) + + // All ArgoCD instances should be reconciled if no label-selctor is applied to the operator. + + // Instance 'a' + req1 := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: a.Name, + Namespace: a.Namespace, + }, + } + res1, err := rt.Reconcile(context.TODO(), req1) + assert.NoError(t, err) + if res1.Requeue { + t.Fatal("reconcile requeued request") + } + + //Instance 'b' + req2 := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: b.Name, + Namespace: b.Namespace, + }, + } + res2, err := rt.Reconcile(context.TODO(), req2) + assert.NoError(t, err) + if res2.Requeue { + t.Fatal("reconcile requeued request") + } + + //Instance 'c' + req3 := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: c.Name, + Namespace: c.Namespace, + }, + } + res3, err := rt.Reconcile(context.TODO(), req3) + assert.NoError(t, err) + if res3.Requeue { + t.Fatal("reconcile requeued request") + } + + // Apply label-selector foo=bar to the operator. + // Only Instance a should reconcile with matching label "foo=bar" + // No reconciliation is expected for instance b and c and an error is expected. + rt.LabelSelector = "foo=bar" + reqTest := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: a.Name, + Namespace: a.Namespace, + }, + } + resTest, err := rt.Reconcile(context.TODO(), reqTest) + assert.NoError(t, err) + if resTest.Requeue { + t.Fatal("reconcile requeued request") + } + + // Instance 'b' is not reconciled as the label does not match, error expected + reqTest2 := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: b.Name, + Namespace: b.Namespace, + }, + } + resTest2, err := rt.Reconcile(context.TODO(), reqTest2) + assert.Error(t, err) + if resTest2.Requeue { + t.Fatal("reconcile requeued request") + } + + //Instance 'c' is not reconciled as there is no label, error expected + reqTest3 := reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: c.Name, + Namespace: c.Namespace, + }, + } + resTest3, err := rt.Reconcile(context.TODO(), reqTest3) + assert.Error(t, err) + if resTest3.Requeue { + t.Fatal("reconcile requeued request") + } +} + func TestReconcileArgoCD_Reconcile_RemoveManagedByLabelOnArgocdDeletion(t *testing.T) { logf.SetLogger(ZapLogger(true)) diff --git a/docs/usage/environment_variables.md b/docs/usage/environment_variables.md index 2a2e3451c..8faaa568e 100644 --- a/docs/usage/environment_variables.md +++ b/docs/usage/environment_variables.md @@ -7,6 +7,7 @@ The following environment variables are available in `argocd-operator`: | `CONTROLLER_CLUSTER_ROLE` | none | Administrators can configure a common cluster role for all the managed namespaces in role bindings for the Argo CD application controller with this environment variable. Note: If this environment variable contains custom roles, the Operator doesn't create the default admin role. Instead, it uses the existing custom role for all managed namespaces. | | `SERVER_CLUSTER_ROLE` | none | Administrators can configure a common cluster role for all the managed namespaces in role bindings for the Argo CD server with this environment variable. Note: If this environment variable contains custom roles, the Operator doesn’t create the default admin role. Instead, it uses the existing custom role for all managed namespaces. | | `REMOVE_MANAGED_BY_LABEL_ON_ARGOCD_DELETION` | false | When an Argo CD instance is deleted, namespaces managed by that instance (via the `argocd.argoproj.io/managed-by` label ) will retain the label by default. Users can change this behavior by setting the environment variable `REMOVE_MANAGED_BY_LABEL_ON_ARGOCD_DELETION` to `true` in the Subscription. | +| `ARGOCD_LABEL_SELECTOR` | none | The label selector can be set on argocd-opertor by exporting `ARGOCD_LABEL_SELECTOR` (eg: `export ARGOCD_LABEL_SELECTOR=foo=bar`). The labels can be added to the argocd instances using the command `kubectl label argocd test1 foo=bar -n test-argocd`. This will enable the operator instance to be tailored to oversee only the corresponding ArgoCD instances having the matching label selector. | Custom Environment Variables are supported in `applicationSet`, `controller`, `notifications`, `repo` and `server` components. For example: diff --git a/go.mod b/go.mod index adb4eb2a3..db4a3b1cb 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -63,6 +64,7 @@ require ( github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.43.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/go.sum b/go.sum index 841ce8cbf..6821bd596 100644 --- a/go.sum +++ b/go.sum @@ -117,6 +117,8 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/argoproj/argo-cd/v2 v2.8.3 h1:ybJ7eNoP7/u5Vqncais6WeVRBEGmZmriAIwLEKmWHIA= github.com/argoproj/argo-cd/v2 v2.8.3/go.mod h1:Pkw7r6HKh5k/5Ynl4MvwCG79ktYBk+7PbJxCjXSlT30= +github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= +github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -135,6 +137,7 @@ github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.31.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= @@ -226,6 +229,7 @@ github.com/coreos/prometheus-operator v0.40.0/go.mod h1:QOoL5cVI3b1OHgpw8s+pH+Ok github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -273,6 +277,7 @@ github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNE github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -310,6 +315,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -345,6 +351,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= @@ -661,6 +668,7 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/flux v0.65.0/go.mod h1:BwN2XG2lMszOoquQaFdPET8FRQfrXiZsWmcMO9rkaVY= github.com/influxdata/influxdb v1.7.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.8.0/go.mod h1:SIzcnsjaHRFpmlxpJ4S3NT64qtEKYweNTUMb/vh0OMQ= @@ -680,6 +688,8 @@ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= @@ -716,7 +726,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -802,8 +816,11 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU= github.com/mikefarah/yq/v2 v2.4.1/go.mod h1:i8SYf1XdgUvY2OFwSqGAtWOOgimD2McJ6iutoxRm4k0= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= +github.com/minio/minio-go/v7 v7.0.58/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -862,6 +879,7 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1034,9 +1052,11 @@ github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190810000440-0ceca61e4d75/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -1068,6 +1088,9 @@ github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -1090,6 +1113,7 @@ github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1271,6 +1295,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1308,6 +1334,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1372,7 +1399,10 @@ golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1401,6 +1431,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1499,15 +1530,23 @@ golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1518,7 +1557,10 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1606,6 +1648,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1761,6 +1804,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1823,6 +1867,7 @@ k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= diff --git a/main.go b/main.go index d04c90e45..1cfecade7 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ import ( goruntime "runtime" "strings" + "github.com/argoproj/argo-cd/v2/util/env" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" appsv1 "github.com/openshift/api/apps/v1" configv1 "github.com/openshift/api/config/v1" @@ -42,6 +43,7 @@ import ( // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -79,8 +81,10 @@ func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string + var labelSelectorFlag string flag.StringVar(&metricsAddr, "metrics-bind-address", fmt.Sprintf(":%d", common.OperatorMetricsPort), "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.StringVar(&labelSelectorFlag, "label-selector", env.StringFromEnv(common.ArgoCDLabelSelectorKey, common.ArgoCDDefaultLabelSelector), "The label selector is used to map to a subset of ArgoCD instances to reconcile") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") @@ -94,6 +98,13 @@ func main() { printVersion() + // Check the label selector format eg. "foo=bar" + if _, err := labels.Parse(labelSelectorFlag); err != nil { + setupLog.Error(err, "error parsing the labelSelector '%s'.", labelSelectorFlag) + os.Exit(1) + } + setupLog.Info(fmt.Sprintf("Watching labelselector \"%s\"", labelSelectorFlag)) + // Inspect cluster to verify availability of extra features if err := argocd.InspectCluster(); err != nil { setupLog.Info("unable to inspect cluster") @@ -185,8 +196,9 @@ func main() { } if err = (&argocd.ReconcileArgoCD{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + LabelSelector: labelSelectorFlag, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "ArgoCD") os.Exit(1) From 8aca0ed6ea585dfc7f6b6559933e2ac98d74a5ee Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Fri, 20 Oct 2023 15:33:54 -0400 Subject: [PATCH 31/94] Addressed discussed a few points Signed-off-by: Yi Cai --- common/constants.go | 43 ++++++++++ common/values.go | 3 +- .../argocd/appcontroller/appcontroller.go | 2 +- controllers/argocd/appcontroller/util.go | 21 +++++ .../argocd/applicationset/applicationset.go | 8 +- .../applicationset/applicationset_test.go | 4 +- .../argocd/applicationset/constants.go | 14 --- .../argocd/applicationset/deployment.go | 14 +-- .../argocd/applicationset/webhookroute.go | 4 +- .../applicationset/webhookroute_test.go | 7 +- controllers/argocd/argocd_controller.go | 85 ++++++++++--------- controllers/argocd/argocdcommon/argohelper.go | 62 ++++++++++++++ controllers/argocd/argocdcommon/testing.go | 1 + controllers/argocd/notifications/configmap.go | 9 +- .../argocd/notifications/configmap_test.go | 3 +- controllers/argocd/notifications/constants.go | 8 -- .../argocd/notifications/deployment.go | 2 +- .../argocd/notifications/notifications.go | 6 +- .../notifications/notifications_test.go | 4 +- controllers/argocd/notifications/secret.go | 9 +- .../argocd/notifications/secret_test.go | 3 +- controllers/argocd/redis/constants.go | 13 --- controllers/argocd/redis/redis.go | 5 +- controllers/argocd/redis/util.go | 72 ---------------- controllers/argocd/reposerver/constants.go | 18 ---- controllers/argocd/reposerver/deployment.go | 7 +- .../argocd/reposerver/deployment_test.go | 41 ++++++--- controllers/argocd/reposerver/reposerver.go | 17 +++- .../argocd/reposerver/reposerver_test.go | 10 ++- controllers/argocd/reposerver/secret.go | 45 +++++----- controllers/argocd/reposerver/secret_test.go | 45 +--------- controllers/argocd/reposerver/service.go | 2 +- controllers/argocd/reposerver/service_test.go | 12 +-- .../argocd/reposerver/servicemonitor.go | 4 +- .../argocd/reposerver/servicemonitor_test.go | 7 +- controllers/argocd/reposerver/util.go | 38 ++++++--- controllers/argocd/server/server.go | 2 +- controllers/argocd/server/util.go | 18 ++++ 38 files changed, 349 insertions(+), 319 deletions(-) create mode 100644 common/constants.go create mode 100644 controllers/argocd/appcontroller/util.go delete mode 100644 controllers/argocd/applicationset/constants.go delete mode 100644 controllers/argocd/notifications/constants.go delete mode 100644 controllers/argocd/redis/constants.go delete mode 100644 controllers/argocd/redis/util.go delete mode 100644 controllers/argocd/reposerver/constants.go create mode 100644 controllers/argocd/server/util.go diff --git a/common/constants.go b/common/constants.go new file mode 100644 index 000000000..1dd8408e1 --- /dev/null +++ b/common/constants.go @@ -0,0 +1,43 @@ +package common + +const ( + // ApplicationController + ApplicationControllerComponent = "application-controller" + + // Notifications + NotificationsControllerComponent = "notifications-controller" + NotificationsSecretName = "argocd-notifications-secret" + NotificationsConfigMapName = "argocd-notifications-cm" + + // RepoServer + RepoServerControllerComponent = "repo-server" + RepoServerController = "argocd-repo-server" + RepoServerMetrics = "repo-server-metrics" + RepoServerTLSSecretName = "argocd-repo-server-tls" + CopyUtil = "copyutil" + // Commands + UidEntryPointSh = "uid_entrypoint.sh" + ArgoCDRepoServer = "--argocd-repo-server" + RepoServerTLSRedisCertPath = "/app/config/reposerver/tls/redis/tls.crt" + + // Server + ServerControllerComponent = "server" + + // Redis + RedisControllerComponent = "redis" + RedisHAProxyServiceName = "redis-ha-haproxy" + // Commands + Redis = "--redis" + RedisUseTLS = "--redis-use-tls" + RedisInsecureSkipTLSVerify = "--redis-insecure-skip-tls-verify" + RedisCACertificate = "--redis-ca-certificate" + + // ApplicationSet + AppSetControllerComponent = "applicationset-controller" + AppSetController = "argocd-applicationset-controller" + AppSetGitlabSCMTlsCert = "appset-gitlab-scm-tls-cert" + AppSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" + AppSetWebhookRouteName = "applicationset-controller-webhook" + // Commands + EntryPointSh = "entrypoint.sh" +) diff --git a/common/values.go b/common/values.go index e19e85730..4937f211e 100644 --- a/common/values.go +++ b/common/values.go @@ -100,5 +100,6 @@ const ( // Commnds const ( - LogLevel = "--loglevel" + LogLevel = "--loglevel" + LogFormat = "--logformat" ) diff --git a/controllers/argocd/appcontroller/appcontroller.go b/controllers/argocd/appcontroller/appcontroller.go index dac1fa2ed..303d530a4 100644 --- a/controllers/argocd/appcontroller/appcontroller.go +++ b/controllers/argocd/appcontroller/appcontroller.go @@ -8,7 +8,7 @@ import ( ) type AppControllerReconciler struct { - Client *client.Client + Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD ClusterScoped bool diff --git a/controllers/argocd/appcontroller/util.go b/controllers/argocd/appcontroller/util.go new file mode 100644 index 000000000..404c989e7 --- /dev/null +++ b/controllers/argocd/appcontroller/util.go @@ -0,0 +1,21 @@ +package appcontroller + +import ( + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" +) + +func (acr *AppControllerReconciler) TriggerAppControllerStatefulSetRollout() error { + name := util.NameWithSuffix(acr.Instance.Name, common.ApplicationControllerComponent) + return workloads.TriggerStatefulSetRollout(acr.Client, name, acr.Instance.Namespace, func(name string, namespace string) { + statefulSet, err := workloads.GetStatefulSet(name, namespace, acr.Client) + if err != nil { + acr.Logger.Error(err, "TriggerAppControllerStatefulSetRollout: failed to trigger server deployment", "name", name, "namespace", namespace) + } + if statefulSet.Spec.Template.ObjectMeta.Labels == nil { + statefulSet.Spec.Template.ObjectMeta.Labels = make(map[string]string) + } + statefulSet.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() + }) +} diff --git a/controllers/argocd/applicationset/applicationset.go b/controllers/argocd/applicationset/applicationset.go index 5b644a251..280eedddc 100644 --- a/controllers/argocd/applicationset/applicationset.go +++ b/controllers/argocd/applicationset/applicationset.go @@ -24,10 +24,10 @@ var ( func (asr *ApplicationSetReconciler) Reconcile() error { - asr.Logger = ctrl.Log.WithName(AppSetControllerComponent).WithValues("instance", asr.Instance.Name, "instance-namespace", asr.Instance.Namespace) + asr.Logger = ctrl.Log.WithName(common.AppSetControllerComponent).WithValues("instance", asr.Instance.Name, "instance-namespace", asr.Instance.Namespace) - resourceName = util.GenerateUniqueResourceName(asr.Instance.Name, asr.Instance.Namespace, AppSetControllerComponent) - resourceLabels = common.DefaultLabels(resourceName, asr.Instance.Name, AppSetControllerComponent) + resourceName = util.GenerateUniqueResourceName(asr.Instance.Name, asr.Instance.Namespace, common.AppSetControllerComponent) + resourceLabels = common.DefaultLabels(resourceName, asr.Instance.Name, common.AppSetControllerComponent) if err := asr.reconcileServiceAccount(); err != nil { asr.Logger.Info("reconciling applicationSet serviceaccount") @@ -50,7 +50,7 @@ func (asr *ApplicationSetReconciler) Reconcile() error { return err } } else { - if err := asr.deleteWebhookRoute(AppSetWebhookRouteName, asr.Instance.Namespace); err != nil { + if err := asr.deleteWebhookRoute(common.AppSetWebhookRouteName, asr.Instance.Namespace); err != nil { asr.Logger.Error(err, "deleting applicationSet webhook route: failed to delete webhook route") return err } diff --git a/controllers/argocd/applicationset/applicationset_test.go b/controllers/argocd/applicationset/applicationset_test.go index 7f60ee263..4b3ea4799 100644 --- a/controllers/argocd/applicationset/applicationset_test.go +++ b/controllers/argocd/applicationset/applicationset_test.go @@ -14,7 +14,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, AppSetControllerComponent) +var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.AppSetControllerComponent) func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bool, objs ...runtime.Object) *ApplicationSetReconciler { s := scheme.Scheme @@ -23,7 +23,7 @@ func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bo assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(AppSetControllerComponent) + logger := ctrl.Log.WithName(common.AppSetControllerComponent) return &ApplicationSetReconciler{ Client: cl, diff --git a/controllers/argocd/applicationset/constants.go b/controllers/argocd/applicationset/constants.go deleted file mode 100644 index 29661ea06..000000000 --- a/controllers/argocd/applicationset/constants.go +++ /dev/null @@ -1,14 +0,0 @@ -package applicationset - -const ( - // Values - AppSetControllerComponent = "applicationset-controller" - AppSetController = "argocd-applicationset-controller" - AppSetGitlabSCMTlsCert = "appset-gitlab-scm-tls-cert" - AppSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" - AppSetWebhookRouteName = "applicationset-controller-webhook" - - // Commands - EntryPointSh = "entrypoint.sh" - ArgoCDRepoServer = "--argocd-repo-server" -) diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 8fd64282c..c8b3760bd 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -179,10 +179,10 @@ func (asr *ApplicationSetReconciler) getDeploymentRequest(dep appsv1.Deployment) func (asr *ApplicationSetReconciler) getApplicationSetCommand() []string { cmd := make([]string, 0) - cmd = append(cmd, EntryPointSh) - cmd = append(cmd, AppSetController) + cmd = append(cmd, common.EntryPointSh) + cmd = append(cmd, common.AppSetController) - cmd = append(cmd, ArgoCDRepoServer) + cmd = append(cmd, common.ArgoCDRepoServer) cmd = append(cmd, reposerver.GetRepoServerAddress(resourceName, asr.Instance.Namespace)) cmd = append(cmd, common.LogLevel) @@ -207,7 +207,7 @@ func (asr *ApplicationSetReconciler) getApplicationSetContainer(addSCMGitlabVolu Command: asr.getApplicationSetCommand(), Image: argocdcommon.GetArgoContainerImage(asr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: AppSetController, + Name: common.AppSetController, Env: appSetEnv, Resources: asr.getApplicationSetResources(), SecurityContext: &corev1.SecurityContext{ @@ -256,8 +256,8 @@ func (asr *ApplicationSetReconciler) getApplicationSetContainer(addSCMGitlabVolu if addSCMGitlabVolumeMount { container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ - Name: AppSetGitlabSCMTlsCert, - MountPath: AppSetGitlabSCMTlsCertPath, + Name: common.AppSetGitlabSCMTlsCert, + MountPath: common.AppSetGitlabSCMTlsCertPath, }) } @@ -311,7 +311,7 @@ func (asr *ApplicationSetReconciler) getApplicationSetPodVolumes(addSCMGitlabVol } if addSCMGitlabVolumeMount { volumes = append(volumes, corev1.Volume{ - Name: AppSetGitlabSCMTlsCert, + Name: common.AppSetGitlabSCMTlsCert, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/controllers/argocd/applicationset/webhookroute.go b/controllers/argocd/applicationset/webhookroute.go index 8e6de8a95..ef7efb2ff 100644 --- a/controllers/argocd/applicationset/webhookroute.go +++ b/controllers/argocd/applicationset/webhookroute.go @@ -110,7 +110,7 @@ func (asr *ApplicationSetReconciler) getWebhookRouteSpec() routev1.RouteSpec { }, To: routev1.RouteTargetReference{ Kind: common.ServiceKind, - Name: util.NameWithSuffix(asr.Instance.Name, AppSetControllerComponent), + Name: util.NameWithSuffix(asr.Instance.Name, common.AppSetControllerComponent), }, } @@ -143,7 +143,7 @@ func (asr *ApplicationSetReconciler) getWebhookRouteRequest(route routev1.Route) func (asr *ApplicationSetReconciler) getDesiredWebhookRoute() *routev1.Route { desiredWebhook := &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ - Name: AppSetWebhookRouteName, + Name: common.AppSetWebhookRouteName, Namespace: asr.Instance.Namespace, Labels: resourceLabels, Annotations: asr.Instance.Annotations, diff --git a/controllers/argocd/applicationset/webhookroute_test.go b/controllers/argocd/applicationset/webhookroute_test.go index bea86ebc0..8b99cff43 100644 --- a/controllers/argocd/applicationset/webhookroute_test.go +++ b/controllers/argocd/applicationset/webhookroute_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/stretchr/testify/assert" @@ -57,7 +58,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { } updatedWebhookRoute := &routev1.Route{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, updatedWebhookRoute) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: common.AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, updatedWebhookRoute) if err != nil { t.Fatalf("Could not get updated WebhookRoute: %v", err) } @@ -97,7 +98,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabl } webhookRoute := &routev1.Route{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, webhookRoute) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: common.AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, webhookRoute) if err != nil { assert.Equal(t, errors.IsNotFound(err), true) } @@ -125,7 +126,7 @@ func TestApplicationSetReconciler_deleteWebhookRoute(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { asr := tt.setupClient(tt.webhookServerRouteEnabled) - if err := asr.deleteWebhookRoute(AppSetWebhookRouteName, ns.Name); (err != nil) != tt.wantErr { + if err := asr.deleteWebhookRoute(common.AppSetWebhookRouteName, ns.Name); (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") } else { diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index b19eb6938..526a0a001 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -229,30 +229,30 @@ func (r *ArgoCDReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *ArgoCDReconciler) reconcileControllers() error { // core components, return reconciliation errors - // if err := r.SecretController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile secret controller") - // return err - // } + if err := r.SecretController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile secret controller") + return err + } - // if err := r.ConfigMapController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile configmap controller") - // return err - // } + if err := r.ConfigMapController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile configmap controller") + return err + } - // if err := r.AppController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile application controller") - // return err - // } + if err := r.AppController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile application controller") + return err + } - // if err := r.ServerController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile server") - // return err - // } + if err := r.ServerController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile server") + return err + } - // if err := r.RedisController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile redis controller") - // return err - // } + if err := r.RedisController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile redis controller") + return err + } if err := r.ReposerverController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile reposerver controller") @@ -260,25 +260,25 @@ func (r *ArgoCDReconciler) reconcileControllers() error { } // non-core components, don't return reconciliation errors - // if r.Instance.Spec.ApplicationSet != nil { - // if err := r.AppsetController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile applicationset controller") - // } - // } else { - // if err := r.AppsetController.DeleteResources(); err != nil { - // r.Logger.Error(err, "failed to delete applicationset resources") - // } - // } + if r.Instance.Spec.ApplicationSet != nil { + if err := r.AppsetController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile applicationset controller") + } + } else { + if err := r.AppsetController.DeleteResources(); err != nil { + r.Logger.Error(err, "failed to delete applicationset resources") + } + } - // if r.Instance.Spec.Notifications.Enabled { - // if err := r.NotificationsController.Reconcile(); err != nil { - // r.Logger.Error(err, "failed to reconcile notifications controller") - // } - // } else { - // if err := r.NotificationsController.DeleteResources(); err != nil { - // r.Logger.Error(err, "failed to delete notifications resources") - // } - // } + if r.Instance.Spec.Notifications.Enabled { + if err := r.NotificationsController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile notifications controller") + } + } else { + if err := r.NotificationsController.DeleteResources(); err != nil { + r.Logger.Error(err, "failed to delete notifications resources") + } + } if err := r.SSOController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile SSO controller") @@ -303,7 +303,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { } r.RedisController = &redis.RedisReconciler{ - Client: &r.Client, + Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, } @@ -312,10 +312,13 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, + + AppController: r.AppController, + ServerController: r.ServerController, } r.ServerController = &server.ServerReconciler{ - Client: &r.Client, + Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, ClusterScoped: r.ClusterScoped, @@ -330,7 +333,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { } r.AppController = &appcontroller.AppControllerReconciler{ - Client: &r.Client, + Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, ClusterScoped: r.ClusterScoped, diff --git a/controllers/argocd/argocdcommon/argohelper.go b/controllers/argocd/argocdcommon/argohelper.go index e73ed783f..f0c9319bb 100644 --- a/controllers/argocd/argocdcommon/argohelper.go +++ b/controllers/argocd/argocdcommon/argohelper.go @@ -1,6 +1,7 @@ package argocdcommon import ( + "context" "fmt" "os" "strings" @@ -9,7 +10,10 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -71,3 +75,61 @@ func TriggerRollout(client cntrlClient.Client, name, namespace, resType string, return fmt.Errorf("resource of unknown type %T, cannot trigger rollout", resType) } } + +func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, error) { + tlsSecretName := types.NamespacedName{Namespace: instanceNamespace, Name: common.ArgoCDRedisServerTLSSecretName} + var tlsSecretObj corev1.Secret + if err := client.Get(context.TODO(), tlsSecretName, &tlsSecretObj); err != nil { + if !errors.IsNotFound(err) { + return false, err + } + return false, nil + } + + secretOwnerRefs := tlsSecretObj.GetOwnerReferences() + if len(secretOwnerRefs) > 0 { + // OpenShift service CA makes the owner reference for the TLS secret to the + // service, which in turn is owned by the controller. This method performs + // a lookup of the controller through the intermediate owning service. + for _, secretOwner := range secretOwnerRefs { + if IsOwnerOfInterest(secretOwner) { + key := cntrlClient.ObjectKey{Name: secretOwner.Name, Namespace: tlsSecretObj.GetNamespace()} + svc := &corev1.Service{} + // Get the owning object of the secret + if err := client.Get(context.TODO(), key, svc); err != nil { + return false, err + } + + // If there's an object of kind ArgoCD in the owner's list, + // this will be our reconciled object. + serviceOwnerRefs := svc.GetOwnerReferences() + for _, serviceOwner := range serviceOwnerRefs { + if serviceOwner.Kind == "ArgoCD" { + return true, nil + } + } + } + } + } else { + // For secrets without owner (i.e. manually created), we apply some + // heuristics. This may not be as accurate (e.g. if the user made a + // typo in the resource's name), but should be good enough for now. + if _, ok := tlsSecretObj.Annotations[common.ArgoCDArgoprojKeyName]; ok { + return true, nil + } + } + return false, nil +} + +// getRedisServerAddress will return the Redis service address for the given ArgoCD. +func GetRedisServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.HA.Enabled { + return GetRedisHAProxyAddress(cr.Namespace) + } + return util.FqdnServiceRef(common.ArgoCDDefaultRedisSuffix, cr.Namespace, common.ArgoCDDefaultRedisPort) +} + +// getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. +func GetRedisHAProxyAddress(namespace string) string { + return util.FqdnServiceRef(common.RedisHAProxyServiceName, namespace, common.ArgoCDDefaultRedisPort) +} diff --git a/controllers/argocd/argocdcommon/testing.go b/controllers/argocd/argocdcommon/testing.go index 24deed41e..7e1343e21 100644 --- a/controllers/argocd/argocdcommon/testing.go +++ b/controllers/argocd/argocdcommon/testing.go @@ -11,6 +11,7 @@ import ( const ( TestNamespace = "argocd" TestArgoCDName = "argocd" + TestUID = "test-uid" ) var ( diff --git a/controllers/argocd/notifications/configmap.go b/controllers/argocd/notifications/configmap.go index 338f90708..3173b4907 100644 --- a/controllers/argocd/notifications/configmap.go +++ b/controllers/argocd/notifications/configmap.go @@ -1,6 +1,7 @@ package notifications import ( + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/workloads" @@ -15,7 +16,7 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { configMapRequest := workloads.ConfigMapRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: NotificationsConfigMapName, + Name: common.NotificationsConfigMapName, Namespace: nr.Instance.Namespace, Labels: resourceLabels, Annotations: nr.Instance.Annotations, @@ -65,10 +66,10 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { } func (nr *NotificationsReconciler) deleteConfigMap(namespace string) error { - if err := workloads.DeleteConfigMap(NotificationsConfigMapName, namespace, nr.Client); err != nil { - nr.Logger.Error(err, "DeleteConfigMap: failed to delete configMap", "name", NotificationsConfigMapName, "namespace", namespace) + if err := workloads.DeleteConfigMap(common.NotificationsConfigMapName, namespace, nr.Client); err != nil { + nr.Logger.Error(err, "DeleteConfigMap: failed to delete configMap", "name", common.NotificationsConfigMapName, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteConfigMap: configMap deleted", "name", NotificationsConfigMapName, "namespace", namespace) + nr.Logger.V(0).Info("DeleteConfigMap: configMap deleted", "name", common.NotificationsConfigMapName, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/configmap_test.go b/controllers/argocd/notifications/configmap_test.go index 94df5a5b0..4dc6700d1 100644 --- a/controllers/argocd/notifications/configmap_test.go +++ b/controllers/argocd/notifications/configmap_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/stretchr/testify/assert" @@ -40,7 +41,7 @@ func TestNotificationsReconciler_reconcileConfigMap(t *testing.T) { } currentConfigMap := &corev1.ConfigMap{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: NotificationsConfigMapName, Namespace: argocdcommon.TestNamespace}, currentConfigMap) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: common.NotificationsConfigMapName, Namespace: argocdcommon.TestNamespace}, currentConfigMap) if err != nil { t.Fatalf("Could not get current ConfigMap: %v", err) } diff --git a/controllers/argocd/notifications/constants.go b/controllers/argocd/notifications/constants.go deleted file mode 100644 index cd31f4a71..000000000 --- a/controllers/argocd/notifications/constants.go +++ /dev/null @@ -1,8 +0,0 @@ -package notifications - -// Values -const ( - NotificationsControllerComponent = "notifications-controller" - NotificationsSecretName = "argocd-notifications-secret" - NotificationsConfigMapName = "argocd-notifications-cm" -) diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index 09dd0f498..cd0dfe76c 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -152,7 +152,7 @@ func (nr *NotificationsReconciler) getDesiredDeployment() *appsv1.Deployment { Command: nr.GetNotificationsCommand(), Image: argocdcommon.GetArgoContainerImage(nr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: NotificationsControllerComponent, + Name: common.NotificationsControllerComponent, Env: notificationEnv, Resources: nr.GetNotificationsResources(), LivenessProbe: &corev1.Probe{ diff --git a/controllers/argocd/notifications/notifications.go b/controllers/argocd/notifications/notifications.go index 40d4bb97f..18686ac52 100644 --- a/controllers/argocd/notifications/notifications.go +++ b/controllers/argocd/notifications/notifications.go @@ -24,10 +24,10 @@ var ( func (nr *NotificationsReconciler) Reconcile() error { - nr.Logger = ctrl.Log.WithName(NotificationsControllerComponent).WithValues("instance", nr.Instance.Name, "instance-namespace", nr.Instance.Namespace) + nr.Logger = ctrl.Log.WithName(common.NotificationsControllerComponent).WithValues("instance", nr.Instance.Name, "instance-namespace", nr.Instance.Namespace) - resourceName = util.GenerateUniqueResourceName(nr.Instance.Name, nr.Instance.Namespace, NotificationsControllerComponent) - resourceLabels = common.DefaultLabels(resourceName, nr.Instance.Name, NotificationsControllerComponent) + resourceName = util.GenerateUniqueResourceName(nr.Instance.Name, nr.Instance.Namespace, common.NotificationsControllerComponent) + resourceLabels = common.DefaultLabels(resourceName, nr.Instance.Name, common.NotificationsControllerComponent) if err := nr.reconcileServiceAccount(); err != nil { nr.Logger.Info("reconciling notifications serviceaccount") diff --git a/controllers/argocd/notifications/notifications_test.go b/controllers/argocd/notifications/notifications_test.go index 005ad557b..045c6ced9 100644 --- a/controllers/argocd/notifications/notifications_test.go +++ b/controllers/argocd/notifications/notifications_test.go @@ -13,14 +13,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, NotificationsControllerComponent) +var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.NotificationsControllerComponent) func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *NotificationsReconciler { s := scheme.Scheme assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(NotificationsControllerComponent) + logger := ctrl.Log.WithName(common.NotificationsControllerComponent) return &NotificationsReconciler{ Client: cl, diff --git a/controllers/argocd/notifications/secret.go b/controllers/argocd/notifications/secret.go index 0ccb6a926..aff9bd0b1 100644 --- a/controllers/argocd/notifications/secret.go +++ b/controllers/argocd/notifications/secret.go @@ -1,6 +1,7 @@ package notifications import ( + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/workloads" @@ -16,7 +17,7 @@ func (nr *NotificationsReconciler) reconcileSecret() error { secretRequest := workloads.SecretRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: NotificationsSecretName, + Name: common.NotificationsSecretName, Namespace: nr.Instance.Namespace, Labels: resourceLabels, }, @@ -66,10 +67,10 @@ func (nr *NotificationsReconciler) reconcileSecret() error { } func (nr *NotificationsReconciler) deleteSecret(namespace string) error { - if err := workloads.DeleteSecret(NotificationsSecretName, namespace, nr.Client); err != nil { - nr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", NotificationsSecretName, "namespace", namespace) + if err := workloads.DeleteSecret(common.NotificationsSecretName, namespace, nr.Client); err != nil { + nr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", common.NotificationsSecretName, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", NotificationsSecretName, "namespace", namespace) + nr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", common.NotificationsSecretName, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/secret_test.go b/controllers/argocd/notifications/secret_test.go index e51911cf2..126dbea95 100644 --- a/controllers/argocd/notifications/secret_test.go +++ b/controllers/argocd/notifications/secret_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/stretchr/testify/assert" @@ -40,7 +41,7 @@ func TestNotificationsReconciler_reconcileSecret(t *testing.T) { } currentSecret := &corev1.Secret{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: NotificationsSecretName, Namespace: argocdcommon.TestNamespace}, currentSecret) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: common.NotificationsSecretName, Namespace: argocdcommon.TestNamespace}, currentSecret) if err != nil { t.Fatalf("Could not get current Secret: %v", err) } diff --git a/controllers/argocd/redis/constants.go b/controllers/argocd/redis/constants.go deleted file mode 100644 index c8ec901a0..000000000 --- a/controllers/argocd/redis/constants.go +++ /dev/null @@ -1,13 +0,0 @@ -package redis - -const ( - // Values - RedisControllerComponent = "redis" - RedisHAProxyServiceName = "redis-ha-haproxy" - - // Commands - Redis = "--redis" - RedisUseTLS = "--redis-use-tls" - RedisInsecureSkipTLSVerify = "--redis-insecure-skip-tls-verify" - RedisCACertificate = "--redis-ca-certificate" -) diff --git a/controllers/argocd/redis/redis.go b/controllers/argocd/redis/redis.go index a42a46554..89bfcfcbc 100644 --- a/controllers/argocd/redis/redis.go +++ b/controllers/argocd/redis/redis.go @@ -2,6 +2,7 @@ package redis import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" @@ -9,14 +10,14 @@ import ( ) type RedisReconciler struct { - Client *client.Client + Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD Logger logr.Logger } func (rr *RedisReconciler) Reconcile() error { - rr.Logger = ctrl.Log.WithName(RedisControllerComponent).WithValues("instance", rr.Instance.Name, "instance-namespace", rr.Instance.Namespace) + rr.Logger = ctrl.Log.WithName(common.RedisControllerComponent).WithValues("instance", rr.Instance.Name, "instance-namespace", rr.Instance.Namespace) // controller logic goes here return nil diff --git a/controllers/argocd/redis/util.go b/controllers/argocd/redis/util.go deleted file mode 100644 index f987beeb7..000000000 --- a/controllers/argocd/redis/util.go +++ /dev/null @@ -1,72 +0,0 @@ -package redis - -import ( - "context" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/argoproj-labs/argocd-operator/pkg/util" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" -) - -// getRedisServerAddress will return the Redis service address for the given ArgoCD. -func GetRedisServerAddress(cr *argoproj.ArgoCD) string { - if cr.Spec.HA.Enabled { - return GetRedisHAProxyAddress(cr.Namespace) - } - return util.FqdnServiceRef(common.ArgoCDDefaultRedisSuffix, cr.Namespace, common.ArgoCDDefaultRedisPort) -} - -// getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. -func GetRedisHAProxyAddress(namespace string) string { - return util.FqdnServiceRef(RedisHAProxyServiceName, namespace, common.ArgoCDDefaultRedisPort) -} - -func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, error) { - tlsSecretName := types.NamespacedName{Namespace: instanceNamespace, Name: common.ArgoCDRedisServerTLSSecretName} - var tlsSecretObj corev1.Secret - if err := client.Get(context.TODO(), tlsSecretName, &tlsSecretObj); err != nil { - if !errors.IsNotFound(err) { - return false, err - } - return false, nil - } - - secretOwnerRefs := tlsSecretObj.GetOwnerReferences() - if len(secretOwnerRefs) > 0 { - // OpenShift service CA makes the owner reference for the TLS secret to the - // service, which in turn is owned by the controller. This method performs - // a lookup of the controller through the intermediate owning service. - for _, secretOwner := range secretOwnerRefs { - if argocdcommon.IsOwnerOfInterest(secretOwner) { - key := cntrlClient.ObjectKey{Name: secretOwner.Name, Namespace: tlsSecretObj.GetNamespace()} - svc := &corev1.Service{} - // Get the owning object of the secret - if err := client.Get(context.TODO(), key, svc); err != nil { - return false, err - } - - // If there's an object of kind ArgoCD in the owner's list, - // this will be our reconciled object. - serviceOwnerRefs := svc.GetOwnerReferences() - for _, serviceOwner := range serviceOwnerRefs { - if serviceOwner.Kind == "ArgoCD" { - return true, nil - } - } - } - } - } else { - // For secrets without owner (i.e. manually created), we apply some - // heuristics. This may not be as accurate (e.g. if the user made a - // typo in the resource's name), but should be good enough for now. - if _, ok := tlsSecretObj.Annotations[common.ArgoCDArgoprojKeyName]; ok { - return true, nil - } - } - return false, nil -} diff --git a/controllers/argocd/reposerver/constants.go b/controllers/argocd/reposerver/constants.go deleted file mode 100644 index 34f947413..000000000 --- a/controllers/argocd/reposerver/constants.go +++ /dev/null @@ -1,18 +0,0 @@ -package reposerver - -const ( - // Values - RepoServerControllerComponent = "repo-server" - RepoServerController = "argocd-repo-server" - RepoServerMetrics = "repo-server-metrics" - RepoServerTLSSecretName = "argocd-repo-server-tls" - RedisHAProxyServiceName = "redis-ha-haproxy" - CopyUtil = "copyutil" - - // Commands - UidEntryPointSh = "uid_entrypoint.sh" - LogLevel = "--loglevel" - LogFormat = "--logformat" - ArgoCDRepoServer = "--argocd-repo-server" - RepoServerTLSRedisCertPath = "/app/config/reposerver/tls/redis/tls.crt" -) diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 3a3192545..02588b392 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -7,7 +7,6 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/redis" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/util" @@ -25,7 +24,7 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { rsr.Logger.Info("reconciling deployment") - useTLSForRedis, err := redis.ShouldUseTLS(rsr.Client, rsr.Instance.Namespace) + useTLSForRedis, err := argocdcommon.ShouldUseTLS(rsr.Client, rsr.Instance.Namespace) if err != nil { rsr.Logger.Error(err, "reconcileDeployment: failed to determine if TLS should be used for Redis") return err @@ -196,7 +195,7 @@ func (rsr *RepoServerReconciler) getDeploymentRequest(dep appsv1.Deployment) wor func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container { initContainers := []corev1.Container{{ - Name: CopyUtil, + Name: common.CopyUtil, Image: argocdcommon.GetArgoContainerImage(rsr.Instance), Command: argocdcommon.GetArgoCmpServerInitCommand(), ImagePullPolicy: corev1.PullAlways, @@ -236,7 +235,7 @@ func (rsr *RepoServerReconciler) getRepoServerContainers(useTLSForRedis bool) [] Command: rsr.GetRepoServerCommand(useTLSForRedis), Image: argocdcommon.GetArgoContainerImage(rsr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: RepoServerController, + Name: common.RepoServerController, Env: repoServerEnv, Resources: rsr.GetRepoServerResources(), LivenessProbe: &corev1.Probe{ diff --git a/controllers/argocd/reposerver/deployment_test.go b/controllers/argocd/reposerver/deployment_test.go index a6462624c..5ed5db07c 100644 --- a/controllers/argocd/reposerver/deployment_test.go +++ b/controllers/argocd/reposerver/deployment_test.go @@ -15,35 +15,48 @@ func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { resourceName = argocdcommon.TestArgoCDName resourceLabels = testExpectedLabels ns := argocdcommon.MakeTestNamespace() - asr := makeTestRepoServerReconciler(t, ns) - - existingDeployment := asr.getDesiredDeployment(false) // todo + rsr := makeTestRepoServerReconciler(t, ns) tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool + name string + setupClient func(useTLSForRedis bool) *RepoServerReconciler + wantErr bool + useTLSForRedis bool }{ { name: "create a deployment", - setupClient: func() *RepoServerReconciler { + setupClient: func(useTLSForRedis bool) *RepoServerReconciler { return makeTestRepoServerReconciler(t, ns) }, - wantErr: false, + wantErr: false, + useTLSForRedis: false, }, { - name: "update a deployment", - setupClient: func() *RepoServerReconciler { + name: "update a deployment when doesn't use TLS for Redis", + setupClient: func(useTLSForRedis bool) *RepoServerReconciler { + existingDeployment := rsr.getDesiredDeployment(useTLSForRedis) outdatedDeployment := existingDeployment outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" return makeTestRepoServerReconciler(t, outdatedDeployment, ns) }, - wantErr: false, + wantErr: false, + useTLSForRedis: false, + }, + { + name: "update a deployment when use TLS for Redis", + setupClient: func(useTLSForRedis bool) *RepoServerReconciler { + existingDeployment := rsr.getDesiredDeployment(useTLSForRedis) + outdatedDeployment := existingDeployment + outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" + return makeTestRepoServerReconciler(t, outdatedDeployment, ns) + }, + wantErr: false, + useTLSForRedis: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - asr := tt.setupClient() + asr := tt.setupClient(tt.useTLSForRedis) err := asr.reconcileDeployment() if (err != nil) != tt.wantErr { if tt.wantErr { @@ -81,8 +94,8 @@ func TestRepoServerReconciler_DeleteDeployment(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - asr := tt.setupClient() - if err := asr.deleteDeployment(resourceName, ns.Name); (err != nil) != tt.wantErr { + rsr := tt.setupClient() + if err := rsr.deleteDeployment(resourceName, ns.Name); (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") } else { diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index ecc71844b..544e4b3b6 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -10,11 +10,22 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +type AppController interface { + TriggerAppControllerStatefulSetRollout() error +} + +type Server interface { + TriggerServerDeploymentRollout() error +} + type RepoServerReconciler struct { Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD Logger logr.Logger + + AppController AppController + ServerController Server } var ( @@ -23,9 +34,9 @@ var ( ) func (rsr *RepoServerReconciler) Reconcile() error { - rsr.Logger = ctrl.Log.WithName(RepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) - resourceName = util.GenerateResourceName(rsr.Instance.Name, RepoServerControllerComponent) - resourceLabels = common.DefaultLabels(resourceName, rsr.Instance.Name, RepoServerControllerComponent) + rsr.Logger = ctrl.Log.WithName(common.RepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) + resourceName = util.GenerateResourceName(rsr.Instance.Name, common.RepoServerControllerComponent) + resourceLabels = common.DefaultLabels(resourceName, rsr.Instance.Name, common.RepoServerControllerComponent) if err := rsr.reconcileService(); err != nil { rsr.Logger.Info("reconciling repo server service") diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index 010a28021..6d1463790 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -8,13 +8,14 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, RepoServerControllerComponent) +var testExpectedLabels = common.DefaultLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.RepoServerControllerComponent) const testServiceAccount = "test-service-account" @@ -25,7 +26,7 @@ func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoSer assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(RepoServerControllerComponent) + logger := ctrl.Log.WithName(common.RepoServerControllerComponent) return &RepoServerReconciler{ Client: cl, @@ -34,6 +35,11 @@ func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoSer a.Spec.Repo = argoproj.ArgoCDRepoSpec{ ServiceAccount: testServiceAccount, } + a.ObjectMeta = metav1.ObjectMeta{ + Name: argocdcommon.TestArgoCDName, + Namespace: argocdcommon.TestNamespace, + UID: argocdcommon.TestUID, + } }), Logger: logger, } diff --git a/controllers/argocd/reposerver/secret.go b/controllers/argocd/reposerver/secret.go index 00a47ea9d..654298ed8 100644 --- a/controllers/argocd/reposerver/secret.go +++ b/controllers/argocd/reposerver/secret.go @@ -6,10 +6,7 @@ import ( "fmt" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/appcontroller" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/cluster" - "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" corev1 "k8s.io/api/core/v1" @@ -27,15 +24,15 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } if namespace.DeletionTimestamp != nil { if err := rsr.deleteTLSSecret(rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) + rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) } return err } - existingSecret, err := workloads.GetSecret(RepoServerTLSSecretName, rsr.Instance.Namespace, rsr.Client) + existingSecret, err := workloads.GetSecret(common.RepoServerTLSSecretName, rsr.Instance.Namespace, rsr.Client) if err != nil { if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) + rsr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) return err } } else if existingSecret.Type != corev1.SecretTypeTLS { @@ -56,27 +53,27 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { err = rsr.Client.Status().Update(context.TODO(), rsr.Instance) // err = workloads.UpdateSecret(desiredSecret, rsr.Client) if err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to update status", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) + rsr.Logger.Error(err, "reconcileSecret: failed to update status", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) return err } // Trigger rollout of API components - components := []string{common.Server, RepoServerControllerComponent, appcontroller.ArgoCDApplicationControllerComponent} - for _, component := range components { - name := util.NameWithSuffix(rsr.Instance.Name, component) - err = argocdcommon.TriggerRollout(rsr.Client, name, rsr.Instance.Namespace, common.DeploymentKind, func(name string, namespace string) { - deployment, err := workloads.GetDeployment(name, namespace, rsr.Client) - if err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to retrieve deployment", "name", name, "namespace", namespace) - } - deployment.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() - }) - if err != nil { - return err - } + err = rsr.TriggerRepoServerDeploymentRollout() + if err != nil { + return err + } + + err = rsr.ServerController.TriggerServerDeploymentRollout() + if err != nil { + return err + } + + err = rsr.AppController.TriggerAppControllerStatefulSetRollout() + if err != nil { + return err } - rsr.Logger.V(0).Info("reconcileSecret: argocd client status updated", "name", RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) + rsr.Logger.V(0).Info("reconcileSecret: argocd client status updated", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) return nil } @@ -84,10 +81,10 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } func (rsr *RepoServerReconciler) deleteTLSSecret(namespace string) error { - if err := workloads.DeleteSecret(RepoServerTLSSecretName, namespace, rsr.Client); err != nil { - rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", RepoServerTLSSecretName, "namespace", namespace) + if err := workloads.DeleteSecret(common.RepoServerTLSSecretName, namespace, rsr.Client); err != nil { + rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", common.RepoServerTLSSecretName, "namespace", namespace) return err } - rsr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", RepoServerTLSSecretName, "namespace", namespace) + rsr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", common.RepoServerTLSSecretName, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/secret_test.go b/controllers/argocd/reposerver/secret_test.go index de6f481fd..eafe55392 100644 --- a/controllers/argocd/reposerver/secret_test.go +++ b/controllers/argocd/reposerver/secret_test.go @@ -1,55 +1,12 @@ package reposerver import ( - "context" "testing" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/stretchr/testify/assert" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" ) -func TestRepoServerReconciler_reconcileSecret(t *testing.T) { - // TODO: Add test cases for updating status from secret change - ns := argocdcommon.MakeTestNamespace() - resourceLabels = testExpectedLabels - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "create a secret", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - nr := tt.setupClient() - err := nr.reconcileTLSSecret() - if (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - - currentSecret := &corev1.Secret{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: RepoServerTLSSecretName, Namespace: argocdcommon.TestNamespace}, currentSecret) - if err != nil { - t.Fatalf("Could not get current Secret: %v", err) - } - assert.Equal(t, testExpectedLabels, currentSecret.ObjectMeta.Labels) - }) - } -} - +// reconcileTLSSecret() will be tested in e2e tests func TestRepoServerReconciler_DeleteSecret(t *testing.T) { ns := argocdcommon.MakeTestNamespace() tests := []struct { diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index 59c3337e4..e6b9df1d0 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -58,7 +58,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desiredService.Name, "namespace", desiredService.Namespace) } - networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Spec.Repo.WantsAutoTLS(), rsr.Logger) + // networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Spec.Repo.WantsAutoTLS(), rsr.Logger) if err = networking.CreateService(desiredService, rsr.Client); err != nil { rsr.Logger.Error(err, "reconcileService: failed to create service", "name", desiredService.Name, "namespace", desiredService.Namespace) diff --git a/controllers/argocd/reposerver/service_test.go b/controllers/argocd/reposerver/service_test.go index 59eed7332..dd84bbaf9 100644 --- a/controllers/argocd/reposerver/service_test.go +++ b/controllers/argocd/reposerver/service_test.go @@ -30,8 +30,8 @@ func TestRepoServerReconciler_reconcileTLSService(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - nr := tt.setupClient() - err := nr.reconcileService() + rsr := tt.setupClient() + err := rsr.reconcileService() if (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") @@ -40,7 +40,7 @@ func TestRepoServerReconciler_reconcileTLSService(t *testing.T) { } } currentService := &corev1.Service{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) + err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) if err != nil { t.Fatalf("Could not get current Service: %v", err) } @@ -61,15 +61,15 @@ func TestRepoServerReconciler_DeleteService(t *testing.T) { { name: "successful delete", setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns, sa) + return makeTestRepoServerReconciler(t, sa, ns) }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - nr := tt.setupClient() - if err := nr.deleteService(resourceName, ns.Name); (err != nil) != tt.wantErr { + rsr := tt.setupClient() + if err := rsr.deleteService(resourceName, ns.Name); (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") } else { diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index f87db24ec..c41db557f 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -18,7 +18,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { serviceMonitorRequest := monitoring.ServiceMonitorRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: util.GenerateResourceName(rsr.Instance.Name, RepoServerMetrics), + Name: util.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetrics), Namespace: rsr.Instance.Namespace, Labels: resourceLabels, Annotations: rsr.Instance.Annotations, @@ -26,7 +26,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ MatchLabels: map[string]string{ - common.AppK8sKeyName: util.GenerateResourceName(rsr.Instance.Name, RepoServerControllerComponent), + common.AppK8sKeyName: util.GenerateResourceName(rsr.Instance.Name, common.RepoServerControllerComponent), }, }, Endpoints: []monitoringv1.Endpoint{ diff --git a/controllers/argocd/reposerver/servicemonitor_test.go b/controllers/argocd/reposerver/servicemonitor_test.go index 73d993d9f..eaa9658e5 100644 --- a/controllers/argocd/reposerver/servicemonitor_test.go +++ b/controllers/argocd/reposerver/servicemonitor_test.go @@ -15,6 +15,7 @@ import ( func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { ns := argocdcommon.MakeTestNamespace() sa := argocdcommon.MakeTestServiceAccount() + resourceName = argocdcommon.TestArgoCDName tests := []struct { @@ -42,7 +43,7 @@ func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { } } currentService := &monitoringv1.ServiceMonitor{} - err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: util.GenerateResourceName(rsr.Instance.Name, RepoServerMetrics), Namespace: argocdcommon.TestNamespace}, currentService) + err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: util.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetrics), Namespace: argocdcommon.TestNamespace}, currentService) if err != nil { t.Fatalf("Could not get current Service: %v", err) } @@ -70,8 +71,8 @@ func TestRepoServerReconciler_DeleteServiceMonitor(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - nr := tt.setupClient() - if err := nr.deleteServiceMonitor(resourceName, ns.Name); (err != nil) != tt.wantErr { + rsr := tt.setupClient() + if err := rsr.deleteServiceMonitor(resourceName, ns.Name); (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") } else { diff --git a/controllers/argocd/reposerver/util.go b/controllers/argocd/reposerver/util.go index f1d96711d..4babd0ae4 100644 --- a/controllers/argocd/reposerver/util.go +++ b/controllers/argocd/reposerver/util.go @@ -2,8 +2,10 @@ package reposerver import ( "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/redis" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" corev1 "k8s.io/api/core/v1" ) @@ -23,25 +25,25 @@ func (rsr *RepoServerReconciler) GetRepoServerResources() corev1.ResourceRequire func (rsr *RepoServerReconciler) GetRepoServerCommand(useTLSForRedis bool) []string { cmd := make([]string, 0) - cmd = append(cmd, UidEntryPointSh) - cmd = append(cmd, RepoServerController) + cmd = append(cmd, common.UidEntryPointSh) + cmd = append(cmd, common.RepoServerController) - cmd = append(cmd, redis.Redis) - cmd = append(cmd, redis.GetRedisServerAddress(rsr.Instance)) + cmd = append(cmd, common.Redis) + cmd = append(cmd, argocdcommon.GetRedisServerAddress(rsr.Instance)) if useTLSForRedis { - cmd = append(cmd, redis.RedisUseTLS) + cmd = append(cmd, common.RedisUseTLS) if rsr.Instance.Spec.Redis.DisableTLSVerification { - cmd = append(cmd, redis.RedisInsecureSkipTLSVerify) + cmd = append(cmd, common.RedisInsecureSkipTLSVerify) } else { - cmd = append(cmd, redis.RedisCACertificate, RepoServerTLSRedisCertPath) + cmd = append(cmd, common.RedisCACertificate, common.RepoServerTLSRedisCertPath) } } - cmd = append(cmd, LogLevel) + cmd = append(cmd, common.LogLevel) cmd = append(cmd, util.GetLogLevel(rsr.Instance.Spec.Repo.LogLevel)) - cmd = append(cmd, LogFormat) + cmd = append(cmd, common.LogFormat) cmd = append(cmd, util.GetLogFormat(rsr.Instance.Spec.Repo.LogFormat)) // *** NOTE *** @@ -66,5 +68,19 @@ func (rsr *RepoServerReconciler) GetRepoServerReplicas() *int32 { // GetRepoServerAddress will return the Argo CD repo server address. func GetRepoServerAddress(name string, namespace string) string { - return util.FqdnServiceRef(util.NameWithSuffix(name, RepoServerControllerComponent), namespace, common.ArgoCDDefaultRepoServerPort) + return util.FqdnServiceRef(util.NameWithSuffix(name, common.RepoServerControllerComponent), namespace, common.ArgoCDDefaultRepoServerPort) +} + +func (rsr *RepoServerReconciler) TriggerRepoServerDeploymentRollout() error { + name := util.NameWithSuffix(rsr.Instance.Name, common.RepoServerControllerComponent) + return workloads.TriggerDeploymentRollout(rsr.Client, name, rsr.Instance.Namespace, func(name string, namespace string) { + deployment, err := workloads.GetDeployment(name, namespace, rsr.Client) + if err != nil { + rsr.Logger.Error(err, "triggerRepoServerDeploymentRollout: failed to trigger repo-server deployment", "name", name, "namespace", namespace) + } + if deployment.Spec.Template.ObjectMeta.Labels == nil { + deployment.Spec.Template.ObjectMeta.Labels = make(map[string]string) + } + deployment.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() + }) } diff --git a/controllers/argocd/server/server.go b/controllers/argocd/server/server.go index c96321f89..5ee20ef22 100644 --- a/controllers/argocd/server/server.go +++ b/controllers/argocd/server/server.go @@ -8,7 +8,7 @@ import ( ) type ServerReconciler struct { - Client *client.Client + Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD ClusterScoped bool diff --git a/controllers/argocd/server/util.go b/controllers/argocd/server/util.go new file mode 100644 index 000000000..37490ccbd --- /dev/null +++ b/controllers/argocd/server/util.go @@ -0,0 +1,18 @@ +package server + +import ( + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" +) + +func (sr *ServerReconciler) TriggerServerDeploymentRollout() error { + name := util.NameWithSuffix(sr.Instance.Name, common.ServerControllerComponent) + return workloads.TriggerDeploymentRollout(sr.Client, name, sr.Instance.Namespace, func(name string, namespace string) { + deployment, err := workloads.GetDeployment(name, namespace, sr.Client) + if err != nil { + sr.Logger.Error(err, "triggerServerDeploymentRollout: failed to trigger server deployment", "name", name, "namespace", namespace) + } + deployment.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() + }) +} From c8e49095b2544422619d6ca033bd01866b03ca70 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 26 Oct 2023 09:51:37 -0400 Subject: [PATCH 32/94] fix: address CVE-2023-39325 (#1022) *address CVE-2023-39325 - upgrade to golang v1.20.10 - disable http/2 for webhook and metrics server, use http/1.1 by default but make it a configurable flag - upgarde k8s library packages to v0.28.3 - Add new structs for keycloak API that were previously part of the (now deprecated) keycloak-operator repo - upgrade to controller-runtime to v0.16.3 - refactor all unit tests --------- Signed-off-by: Jaideep Rao --- .github/workflows/ci-build.yaml | 4 +- .github/workflows/codegen.yaml | 2 +- .github/workflows/go.yml | 2 +- .github/workflows/publish.yaml | 2 +- Dockerfile | 2 +- .../manifests/argoproj.io_argocdexports.yaml | 100 +- bundle/manifests/argoproj.io_argocds.yaml | 3106 +++++++++++------ .../crd/bases/argoproj.io_argocdexports.yaml | 100 +- config/crd/bases/argoproj.io_argocds.yaml | 3106 +++++++++++------ controllers/argocd/applicationset_test.go | 83 +- controllers/argocd/argocd_controller.go | 4 +- controllers/argocd/argocd_controller_test.go | 48 +- controllers/argocd/configmap.go | 4 +- controllers/argocd/configmap_test.go | 138 +- controllers/argocd/custommapper.go | 10 +- controllers/argocd/custommapper_test.go | 165 +- controllers/argocd/deployment_test.go | 286 +- controllers/argocd/dex_test.go | 83 +- controllers/argocd/grafana.go | 5 +- controllers/argocd/hpa_test.go | 11 +- controllers/argocd/ingress_test.go | 43 +- controllers/argocd/keycloak.go | 75 +- controllers/argocd/keycloak_client.go | 7 +- controllers/argocd/keycloak_client_test.go | 3 +- controllers/argocd/keycloak_test.go | 19 +- controllers/argocd/keycloak_types.go | 159 + controllers/argocd/notifications_test.go | 60 +- controllers/argocd/prometheus_test.go | 10 +- controllers/argocd/role.go | 2 - controllers/argocd/role_test.go | 64 +- controllers/argocd/rolebinding.go | 4 +- controllers/argocd/rolebinding_test.go | 55 +- controllers/argocd/route_test.go | 46 +- controllers/argocd/secret_test.go | 56 +- controllers/argocd/service_account_test.go | 20 +- controllers/argocd/sso_test.go | 66 +- controllers/argocd/statefulset_test.go | 92 +- controllers/argocd/status_test.go | 71 +- controllers/argocd/testing.go | 36 +- controllers/argocd/util.go | 33 +- controllers/argocd/util_test.go | 143 +- controllers/suite_testx.go | 10 - .../0.8.0/argoproj.io_argocdexports.yaml | 100 +- .../0.8.0/argoproj.io_argocds.yaml | 3106 +++++++++++------ go.mod | 100 +- go.sum | 1312 ++++++- main.go | 67 +- .../internal/processor/filewriter.go | 4 +- 48 files changed, 8992 insertions(+), 4032 deletions(-) create mode 100644 controllers/argocd/keycloak_types.go diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 28700d9fc..4501b0c97 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -30,7 +30,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.19 + go-version: '1.20' - name: Restore go build cache uses: actions/cache@v1 @@ -75,7 +75,7 @@ jobs: - name: Setup Golang uses: actions/setup-go@v1 with: - go-version: 1.19 + go-version: '1.20' - name: GH actions workaround - Kill XSP4 process run: | sudo pkill mono || true diff --git a/.github/workflows/codegen.yaml b/.github/workflows/codegen.yaml index 92603194d..c7225874e 100644 --- a/.github/workflows/codegen.yaml +++ b/.github/workflows/codegen.yaml @@ -8,7 +8,7 @@ on: - 'master' env: # Golang version to use - GOLANG_VERSION: 1.19 + GOLANG_VERSION: '1.20' # Version of operator-sdk binary SDK_VERSION: 1.11.0 # Checksum of operator-sdk binary diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 8f8ea7bb7..604164431 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.19 + go-version: '1.20' - name: Build run: make build diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index b089e90ca..c7be16460 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.19 + go-version: '1.20' - name: Restore go build cache uses: actions/cache@v1 diff --git a/Dockerfile b/Dockerfile index 964eecc6d..92b21c527 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM golang:1.19 as builder +FROM golang:1.20 as builder WORKDIR /workspace # Copy the Go Modules manifests diff --git a/bundle/manifests/argoproj.io_argocdexports.yaml b/bundle/manifests/argoproj.io_argocdexports.yaml index 8a8b0b0f1..33c64ec9f 100644 --- a/bundle/manifests/argoproj.io_argocdexports.yaml +++ b/bundle/manifests/argoproj.io_argocdexports.yaml @@ -54,20 +54,23 @@ spec: description: PVC is the desired characteristics for a PersistentVolumeClaim. properties: accessModes: - description: 'AccessModes contains the desired access modes + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify either: * - An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + description: 'dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always have the - same contents as the DataSourceRef field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will be copied + to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not + be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the resource being @@ -86,26 +89,32 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which to populate - the volume with data, if a non-empty volume is desired. - This may be any local object from a non-empty API group - (non core object) or a PersistentVolumeClaim object. When - this field is specified, volume binding will only succeed + description: 'dataSourceRef specifies the object from which + to populate the volume with data, if a non-empty volume + is desired. This may be any object from a non-empty API + group (non core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will - replace the functionality of the DataSource field and as + replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same - value. For backwards compatibility, both fields (DataSource - and DataSourceRef) will be set to the same value automatically - if one of them is empty and the other is non-empty. There - are two important differences between DataSource and DataSourceRef: - * While DataSource only allows two specific types of objects, - DataSourceRef allows any non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed values (dropping - them), DataSourceRef preserves all values, and generates - an error if a disallowed value is specified. (Alpha) Using - this field requires the AnyVolumeDataSource feature gate - to be enabled.' + value. For backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource and + dataSourceRef) will be set to the same value automatically + if one of them is empty and the other is non-empty. When + namespace is specified in dataSourceRef, dataSource isn''t + set to the same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, + dataSourceRef allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and generates + an error if a disallowed value is specified. * While dataSource + only allows local objects, dataSourceRef allows objects in + any namespaces. (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the resource being @@ -119,18 +128,50 @@ spec: name: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace of resource being + referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object is + required in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource feature gate to be + enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum resources the + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -152,11 +193,12 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider for binding. + description: selector is a label query over volumes to consider + for binding. properties: matchExpressions: description: matchExpressions is a list of label selector @@ -201,8 +243,8 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of volume is required @@ -210,7 +252,7 @@ spec: in claim spec. type: string volumeName: - description: VolumeName is the binding reference to the PersistentVolume + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index f0a7218e7..e8ba59f6c 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -189,6 +189,28 @@ spec: description: Resources defines the Compute Resources required by the container for ApplicationSet. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -209,7 +231,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -252,12 +275,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -265,13 +288,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -525,6 +548,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Application Controller. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -545,7 +590,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sharding: @@ -608,6 +654,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -628,7 +696,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -696,10 +765,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -709,13 +778,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -726,6 +795,28 @@ spec: description: Resources defines the Compute Resources required by the container for Grafana. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -746,7 +837,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -850,6 +942,28 @@ spec: description: Resources defines the Compute Resources required by the container for HA. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -870,7 +984,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object required: @@ -1139,6 +1254,28 @@ spec: description: Resources defines the Compute Resources required by the container for Argo CD Notifications. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -1159,7 +1296,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -1211,10 +1349,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -1224,13 +1362,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -1363,6 +1501,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -1383,7 +1543,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -1534,11 +1695,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -1549,7 +1710,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -1725,7 +1886,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -1780,7 +1941,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -1879,7 +2043,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -1961,8 +2128,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -1994,7 +2160,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2091,13 +2259,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -2169,8 +2337,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -2202,7 +2369,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2292,10 +2461,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -2317,9 +2530,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -2444,7 +2678,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -2477,15 +2712,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2534,8 +2765,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -2567,7 +2797,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2795,6 +3027,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -2815,7 +3069,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object serviceaccount: @@ -2830,11 +3085,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -2845,7 +3100,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -3021,7 +3276,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -3076,7 +3331,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -3175,7 +3433,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -3257,8 +3518,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3290,7 +3550,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -3387,13 +3649,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -3465,8 +3727,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3498,7 +3759,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -3588,10 +3851,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -3613,9 +3920,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -3740,7 +4068,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -3773,15 +4102,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -3830,8 +4155,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3863,7 +4187,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -4124,122 +4450,124 @@ spec: may be accessed by any container in the pod. properties: awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' format: int32 type: integer readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: boolean volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: string required: - volumeID type: object azureDisk: - description: AzureDisk represents an Azure Data Disk mount + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. properties: cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' type: string diskName: - description: The Name of the data disk in the blob storage + description: diskName is the Name of the data disk in + the blob storage type: string diskURI: - description: The URI the data disk in the blob storage + description: diskURI is the URI of data disk in the + blob storage type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults to shared' type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean required: - diskName - diskURI type: object azureFile: - description: AzureFile represents an Azure File Service + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. properties: readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretName: - description: the name of secret that contains Azure - Storage Account Name and Key + description: secretName is the name of secret that + contains Azure Storage Account Name and Key type: string shareName: - description: Share Name + description: shareName is the azure share Name type: string required: - secretName - shareName type: object cephfs: - description: CephFS represents a Ceph FS mount on the host + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime properties: monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' items: type: string type: array path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' type: string readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: boolean secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4248,30 +4576,30 @@ spec: type: string type: object user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string required: - monitors type: object cinder: - description: 'Cinder represents a cinder volume attached + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string readOnly: - description: 'Optional: Defaults to false (read/write). + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: boolean secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4280,37 +4608,38 @@ spec: type: string type: object volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string required: - volumeID type: object configMap: - description: ConfigMap represents a configMap that should + description: configMap represents a configMap that should populate this volume properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: @@ -4318,26 +4647,26 @@ spec: volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -4349,28 +4678,28 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: - description: Specify whether the ConfigMap or its keys - must be defined + description: optional specify whether the ConfigMap + or its keys must be defined type: boolean type: object csi: - description: CSI (Container Storage Interface) represents + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). properties: driver: - description: Driver is the name of the CSI driver that + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. type: string fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. type: string nodePublishSecretRef: - description: NodePublishSecretRef is a reference to + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, @@ -4385,13 +4714,13 @@ spec: type: string type: object readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). type: boolean volumeAttributes: additionalProperties: type: string - description: VolumeAttributes stores driver-specific + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. type: object @@ -4399,7 +4728,7 @@ spec: - driver type: object downwardAPI: - description: DownwardAPI represents downward API about the + description: downwardAPI represents downward API about the pod that should populate this volume properties: defaultMode: @@ -4489,31 +4818,33 @@ spec: type: array type: object emptyDir: - description: 'EmptyDir represents a temporary directory + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' properties: medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' type: string sizeLimit: anyOf: - type: integer - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object ephemeral: - description: "Ephemeral represents a volume that is handled + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n @@ -4569,24 +4900,27 @@ spec: also valid here. properties: accessModes: - description: 'AccessModes contains the desired + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the @@ -4608,32 +4942,41 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the @@ -4650,12 +4993,23 @@ spec: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than @@ -4663,6 +5017,32 @@ spec: capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -4686,12 +5066,13 @@ spec: If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider - for binding. + description: selector is a label query over + volumes to consider for binding. properties: matchExpressions: description: matchExpressions is a list @@ -4742,8 +5123,9 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of @@ -4752,7 +5134,7 @@ spec: claim spec. type: string volumeName: - description: VolumeName is the binding reference + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object @@ -4761,32 +5143,34 @@ spec: type: object type: object fc: - description: FC represents a Fibre Channel resource that + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' type: string lun: - description: 'Optional: FC target lun number' + description: 'lun is Optional: FC target lun number' format: int32 type: integer readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' items: type: string type: array wwids: - description: 'Optional: FC volume world wide identifiers + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' items: @@ -4794,35 +5178,37 @@ spec: type: array type: object flexVolume: - description: FlexVolume represents a generic volume resource + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. properties: driver: - description: Driver is the name of the driver to use + description: driver is the name of the driver to use for this volume. type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. type: string options: additionalProperties: type: string - description: 'Optional: Extra command options if any.' + description: 'options is Optional: this field holds + extra command options if any.' type: object readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4834,49 +5220,50 @@ spec: - driver type: object flocker: - description: Flocker represents a Flocker volume attached + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated type: string datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset type: string type: object gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' format: int32 type: integer pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: boolean @@ -4884,42 +5271,43 @@ spec: - pdName type: object gitRepo: - description: 'GitRepo represents a git repository at a particular + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' properties: directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. type: string repository: - description: Repository URL + description: repository is the URL type: string revision: - description: Commit hash for the specified revision. + description: revision is the commit hash for the specified + revision. type: string required: - repository type: object glusterfs: - description: 'Glusterfs represents a Glusterfs mount on + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' properties: endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string path: - description: 'Path is the Glusterfs volume path. More + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string readOnly: - description: 'ReadOnly here will force the Glusterfs + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: boolean @@ -4928,7 +5316,7 @@ spec: - path type: object hostPath: - description: 'HostPath represents a pre-existing file or + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the @@ -4939,68 +5327,71 @@ spec: as read/write.' properties: path: - description: 'Path of the directory on the host. If + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string type: - description: 'Type for HostPath Volume Defaults to "" + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string required: - path type: object iscsi: - description: 'ISCSI represents an ISCSI Disk resource that + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' properties: chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication type: boolean chapAuthSession: - description: whether support iSCSI Session CHAP authentication + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication type: boolean fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' type: string initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. type: string iqn: - description: Target iSCSI Qualified Name. + description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). type: string lun: - description: iSCSI Target Lun number. + description: lun represents iSCSI Target Lun number. format: int32 type: integer portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). items: type: string type: array readOnly: - description: ReadOnly here will force the ReadOnly setting + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. type: boolean secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -5009,9 +5400,10 @@ spec: type: string type: object targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). type: string required: - iqn @@ -5019,24 +5411,24 @@ spec: - targetPortal type: object name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string nfs: - description: 'NFS represents an NFS mount on the host that + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' properties: path: - description: 'Path that is exported by the NFS server. + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string readOnly: - description: 'ReadOnly here will force the NFS export + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: boolean server: - description: 'Server is the hostname or IP address of + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string required: @@ -5044,89 +5436,89 @@ spec: - server type: object persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' properties: claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' type: string readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. type: boolean required: - claimName type: object photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string pdID: - description: ID that identifies Photon Controller persistent - disk + description: pdID is the ID that identifies Photon Controller + persistent disk type: string required: - pdID type: object portworxVolume: - description: PortworxVolume represents a portworx volume + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine properties: fsType: - description: FSType represents the filesystem type to + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean volumeID: - description: VolumeID uniquely identifies a Portworx + description: volumeID uniquely identifies a Portworx volume type: string required: - volumeID type: object projected: - description: Items for all in one resources secrets, configmaps, - and downward API + description: projected items for all in one resources secrets, + configmaps, and downward API properties: defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. format: int32 type: integer sources: - description: list of volume projections + description: sources is the list of volume projections items: description: Projection that may be projected along with other supported volume types properties: configMap: - description: information about the configMap data - to project + description: configMap information about the configMap + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content @@ -5143,27 +5535,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -5179,13 +5571,13 @@ spec: kind, uid?' type: string optional: - description: Specify whether the ConfigMap - or its keys must be defined + description: optional specify whether the + ConfigMap or its keys must be defined type: boolean type: object downwardAPI: - description: information about the downwardAPI - data to project + description: downwardAPI information about the + downwardAPI data to project properties: items: description: Items is a list of DownwardAPIVolume @@ -5269,11 +5661,11 @@ spec: type: array type: object secret: - description: information about the secret data - to project + description: secret information about the secret + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content @@ -5290,27 +5682,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -5326,16 +5718,16 @@ spec: kind, uid?' type: string optional: - description: Specify whether the Secret or - its key must be defined + description: optional field specify whether + the Secret or its key must be defined type: boolean type: object serviceAccountToken: - description: information about the serviceAccountToken - data to project + description: serviceAccountToken is information + about the serviceAccountToken data to project properties: audience: - description: Audience is the intended audience + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise @@ -5343,7 +5735,7 @@ spec: to the identifier of the apiserver. type: string expirationSeconds: - description: ExpirationSeconds is the requested + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively @@ -5356,7 +5748,7 @@ spec: format: int64 type: integer path: - description: Path is the path relative to + description: path is the path relative to the mount point of the file to project the token into. type: string @@ -5367,35 +5759,35 @@ spec: type: array type: object quobyte: - description: Quobyte represents a Quobyte mount on the host + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime properties: group: - description: Group to map volume access to Default is + description: group to map volume access to Default is no group type: string readOnly: - description: ReadOnly here will force the Quobyte volume + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. type: boolean registry: - description: Registry represents a single or multiple + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes type: string tenant: - description: Tenant owning the given Quobyte volume + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin type: string user: - description: User to map volume access to Defaults to + description: user to map volume access to Defaults to serivceaccount user type: string volume: - description: Volume is a string that references an already + description: volume is a string that references an already created Quobyte volume by name. type: string required: @@ -5403,43 +5795,44 @@ spec: - volume type: object rbd: - description: 'RBD represents a Rados Block Device mount + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' type: string image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string keyring: - description: 'Keyring is the path to key ring for RBDUser. + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' items: type: string type: array pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: boolean secretRef: - description: 'SecretRef is name of the authentication + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' properties: @@ -5450,35 +5843,36 @@ spec: type: string type: object user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string required: - image - monitors type: object scaleIO: - description: ScaleIO represents a ScaleIO persistent volume + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". type: string gateway: - description: The host address of the ScaleIO API Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef references to the secret for + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. properties: @@ -5489,26 +5883,26 @@ spec: type: string type: object sslEnabled: - description: Flag to enable/disable SSL communication + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false type: boolean storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. type: string storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. type: string system: - description: The name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system + as configured in ScaleIO. type: string volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. type: string required: - gateway @@ -5516,57 +5910,58 @@ spec: - system type: object secret: - description: 'Secret represents a secret that should populate + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -5574,30 +5969,30 @@ spec: type: object type: array optional: - description: Specify whether the Secret or its keys - must be defined + description: optional field specify whether the Secret + or its keys must be defined type: boolean secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' type: string type: object storageos: - description: StorageOS represents a StorageOS volume attached + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef specifies the secret to use for + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. properties: @@ -5608,12 +6003,12 @@ spec: type: string type: object volumeName: - description: VolumeName is the human-readable name of + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. type: string volumeNamespace: - description: VolumeNamespace specifies the scope of + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within @@ -5625,25 +6020,26 @@ spec: type: string type: object vsphereVolume: - description: VsphereVolume represents a vSphere volume attached + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. type: string volumePath: - description: Path that identifies vSphere volume vmdk + description: volumePath is the path that identifies + vSphere volume vmdk type: string required: - volumePath @@ -5764,8 +6160,9 @@ spec: for the Argo CD Server component. properties: maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. format: int32 type: integer minReplicas: @@ -5784,23 +6181,26 @@ spec: Scale subresource. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the + referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. format: int32 type: integer required: @@ -5964,12 +6364,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5977,13 +6377,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -6022,10 +6422,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -6035,13 +6435,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -6071,6 +6471,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Argo CD server component. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6091,7 +6513,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -6211,6 +6634,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6232,7 +6677,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -6254,6 +6699,28 @@ spec: description: Resources defines the Compute Resources required by the container for Keycloak. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6275,7 +6742,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object rootCA: @@ -6298,6 +6765,28 @@ spec: Resources defines the Compute Resources required by the container for SSO. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6318,7 +6807,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object verifyTLS: @@ -6632,6 +7122,28 @@ spec: description: Resources defines the Compute Resources required by the container for ApplicationSet. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6652,7 +7164,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object scmRootCAConfigMap: @@ -6700,12 +7213,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -6713,13 +7226,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -6973,6 +7486,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Application Controller. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6993,7 +7528,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sharding: @@ -7093,10 +7629,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -7106,13 +7642,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -7123,6 +7659,28 @@ spec: description: Resources defines the Compute Resources required by the container for Grafana. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7143,7 +7701,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -7247,6 +7806,28 @@ spec: description: Resources defines the Compute Resources required by the container for HA. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7267,7 +7848,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object required: @@ -7536,6 +8118,28 @@ spec: description: Resources defines the Compute Resources required by the container for Argo CD Notifications. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7556,7 +8160,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -7608,10 +8213,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -7621,13 +8226,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -7760,6 +8365,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7780,7 +8407,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -7931,11 +8559,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -7946,7 +8574,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -8122,7 +8750,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -8177,7 +8805,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -8276,7 +8907,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -8358,8 +8992,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8391,7 +9024,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -8488,13 +9123,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -8566,8 +9201,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8599,7 +9233,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -8689,10 +9325,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -8714,9 +9394,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -8841,7 +9542,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -8874,15 +9576,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -8931,8 +9629,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8964,7 +9661,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9192,6 +9891,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -9212,7 +9933,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object serviceaccount: @@ -9227,11 +9949,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -9242,7 +9964,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -9418,7 +10140,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -9473,7 +10195,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -9572,7 +10297,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -9654,8 +10382,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -9687,7 +10414,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9784,13 +10513,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -9862,8 +10591,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -9895,7 +10623,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9985,10 +10715,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -10010,9 +10784,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -10137,7 +10932,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -10170,15 +10966,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -10227,8 +11019,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -10260,7 +11051,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -10521,122 +11314,124 @@ spec: may be accessed by any container in the pod. properties: awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' format: int32 type: integer readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: boolean volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: string required: - volumeID type: object azureDisk: - description: AzureDisk represents an Azure Data Disk mount + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. properties: cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' type: string diskName: - description: The Name of the data disk in the blob storage + description: diskName is the Name of the data disk in + the blob storage type: string diskURI: - description: The URI the data disk in the blob storage + description: diskURI is the URI of data disk in the + blob storage type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults to shared' type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean required: - diskName - diskURI type: object azureFile: - description: AzureFile represents an Azure File Service + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. properties: readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretName: - description: the name of secret that contains Azure - Storage Account Name and Key + description: secretName is the name of secret that + contains Azure Storage Account Name and Key type: string shareName: - description: Share Name + description: shareName is the azure share Name type: string required: - secretName - shareName type: object cephfs: - description: CephFS represents a Ceph FS mount on the host + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime properties: monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' items: type: string type: array path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' type: string readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: boolean secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -10645,30 +11440,30 @@ spec: type: string type: object user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string required: - monitors type: object cinder: - description: 'Cinder represents a cinder volume attached + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string readOnly: - description: 'Optional: Defaults to false (read/write). + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: boolean secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -10677,37 +11472,38 @@ spec: type: string type: object volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string required: - volumeID type: object configMap: - description: ConfigMap represents a configMap that should + description: configMap represents a configMap that should populate this volume properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: @@ -10715,26 +11511,26 @@ spec: volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -10746,28 +11542,28 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: - description: Specify whether the ConfigMap or its keys - must be defined + description: optional specify whether the ConfigMap + or its keys must be defined type: boolean type: object csi: - description: CSI (Container Storage Interface) represents + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). properties: driver: - description: Driver is the name of the CSI driver that + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. type: string fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. type: string nodePublishSecretRef: - description: NodePublishSecretRef is a reference to + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, @@ -10782,13 +11578,13 @@ spec: type: string type: object readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). type: boolean volumeAttributes: additionalProperties: type: string - description: VolumeAttributes stores driver-specific + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. type: object @@ -10796,7 +11592,7 @@ spec: - driver type: object downwardAPI: - description: DownwardAPI represents downward API about the + description: downwardAPI represents downward API about the pod that should populate this volume properties: defaultMode: @@ -10886,31 +11682,33 @@ spec: type: array type: object emptyDir: - description: 'EmptyDir represents a temporary directory + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' properties: medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' type: string sizeLimit: anyOf: - type: integer - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object ephemeral: - description: "Ephemeral represents a volume that is handled + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n @@ -10966,24 +11764,27 @@ spec: also valid here. properties: accessModes: - description: 'AccessModes contains the desired + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the @@ -11005,32 +11806,41 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the @@ -11047,12 +11857,23 @@ spec: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than @@ -11060,6 +11881,32 @@ spec: capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -11083,12 +11930,13 @@ spec: If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider - for binding. + description: selector is a label query over + volumes to consider for binding. properties: matchExpressions: description: matchExpressions is a list @@ -11139,8 +11987,9 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of @@ -11149,7 +11998,7 @@ spec: claim spec. type: string volumeName: - description: VolumeName is the binding reference + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object @@ -11158,32 +12007,34 @@ spec: type: object type: object fc: - description: FC represents a Fibre Channel resource that + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' type: string lun: - description: 'Optional: FC target lun number' + description: 'lun is Optional: FC target lun number' format: int32 type: integer readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' items: type: string type: array wwids: - description: 'Optional: FC volume world wide identifiers + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' items: @@ -11191,35 +12042,37 @@ spec: type: array type: object flexVolume: - description: FlexVolume represents a generic volume resource + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. properties: driver: - description: Driver is the name of the driver to use + description: driver is the name of the driver to use for this volume. type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. type: string options: additionalProperties: type: string - description: 'Optional: Extra command options if any.' + description: 'options is Optional: this field holds + extra command options if any.' type: object readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -11231,49 +12084,50 @@ spec: - driver type: object flocker: - description: Flocker represents a Flocker volume attached + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated type: string datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset type: string type: object gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' format: int32 type: integer pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: boolean @@ -11281,42 +12135,43 @@ spec: - pdName type: object gitRepo: - description: 'GitRepo represents a git repository at a particular + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' properties: directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. type: string repository: - description: Repository URL + description: repository is the URL type: string revision: - description: Commit hash for the specified revision. + description: revision is the commit hash for the specified + revision. type: string required: - repository type: object glusterfs: - description: 'Glusterfs represents a Glusterfs mount on + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' properties: endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string path: - description: 'Path is the Glusterfs volume path. More + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string readOnly: - description: 'ReadOnly here will force the Glusterfs + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: boolean @@ -11325,7 +12180,7 @@ spec: - path type: object hostPath: - description: 'HostPath represents a pre-existing file or + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the @@ -11336,68 +12191,71 @@ spec: as read/write.' properties: path: - description: 'Path of the directory on the host. If + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string type: - description: 'Type for HostPath Volume Defaults to "" + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string required: - path type: object iscsi: - description: 'ISCSI represents an ISCSI Disk resource that + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' properties: chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication type: boolean chapAuthSession: - description: whether support iSCSI Session CHAP authentication + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication type: boolean fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' type: string initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. type: string iqn: - description: Target iSCSI Qualified Name. + description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). type: string lun: - description: iSCSI Target Lun number. + description: lun represents iSCSI Target Lun number. format: int32 type: integer portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). items: type: string type: array readOnly: - description: ReadOnly here will force the ReadOnly setting + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. type: boolean secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -11406,9 +12264,10 @@ spec: type: string type: object targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). type: string required: - iqn @@ -11416,24 +12275,24 @@ spec: - targetPortal type: object name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string nfs: - description: 'NFS represents an NFS mount on the host that + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' properties: path: - description: 'Path that is exported by the NFS server. + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string readOnly: - description: 'ReadOnly here will force the NFS export + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: boolean server: - description: 'Server is the hostname or IP address of + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string required: @@ -11441,89 +12300,89 @@ spec: - server type: object persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' properties: claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' type: string readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. type: boolean required: - claimName type: object photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string pdID: - description: ID that identifies Photon Controller persistent - disk + description: pdID is the ID that identifies Photon Controller + persistent disk type: string required: - pdID type: object portworxVolume: - description: PortworxVolume represents a portworx volume + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine properties: fsType: - description: FSType represents the filesystem type to + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean volumeID: - description: VolumeID uniquely identifies a Portworx + description: volumeID uniquely identifies a Portworx volume type: string required: - volumeID type: object projected: - description: Items for all in one resources secrets, configmaps, - and downward API + description: projected items for all in one resources secrets, + configmaps, and downward API properties: defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. format: int32 type: integer sources: - description: list of volume projections + description: sources is the list of volume projections items: description: Projection that may be projected along with other supported volume types properties: configMap: - description: information about the configMap data - to project + description: configMap information about the configMap + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content @@ -11540,27 +12399,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -11576,13 +12435,13 @@ spec: kind, uid?' type: string optional: - description: Specify whether the ConfigMap - or its keys must be defined + description: optional specify whether the + ConfigMap or its keys must be defined type: boolean type: object downwardAPI: - description: information about the downwardAPI - data to project + description: downwardAPI information about the + downwardAPI data to project properties: items: description: Items is a list of DownwardAPIVolume @@ -11666,11 +12525,11 @@ spec: type: array type: object secret: - description: information about the secret data - to project + description: secret information about the secret + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content @@ -11687,27 +12546,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -11723,16 +12582,16 @@ spec: kind, uid?' type: string optional: - description: Specify whether the Secret or - its key must be defined + description: optional field specify whether + the Secret or its key must be defined type: boolean type: object serviceAccountToken: - description: information about the serviceAccountToken - data to project + description: serviceAccountToken is information + about the serviceAccountToken data to project properties: audience: - description: Audience is the intended audience + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise @@ -11740,7 +12599,7 @@ spec: to the identifier of the apiserver. type: string expirationSeconds: - description: ExpirationSeconds is the requested + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively @@ -11753,7 +12612,7 @@ spec: format: int64 type: integer path: - description: Path is the path relative to + description: path is the path relative to the mount point of the file to project the token into. type: string @@ -11764,35 +12623,35 @@ spec: type: array type: object quobyte: - description: Quobyte represents a Quobyte mount on the host + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime properties: group: - description: Group to map volume access to Default is + description: group to map volume access to Default is no group type: string readOnly: - description: ReadOnly here will force the Quobyte volume + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. type: boolean registry: - description: Registry represents a single or multiple + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes type: string tenant: - description: Tenant owning the given Quobyte volume + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin type: string user: - description: User to map volume access to Defaults to + description: user to map volume access to Defaults to serivceaccount user type: string volume: - description: Volume is a string that references an already + description: volume is a string that references an already created Quobyte volume by name. type: string required: @@ -11800,43 +12659,44 @@ spec: - volume type: object rbd: - description: 'RBD represents a Rados Block Device mount + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' type: string image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string keyring: - description: 'Keyring is the path to key ring for RBDUser. + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' items: type: string type: array pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: boolean secretRef: - description: 'SecretRef is name of the authentication + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' properties: @@ -11847,35 +12707,36 @@ spec: type: string type: object user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string required: - image - monitors type: object scaleIO: - description: ScaleIO represents a ScaleIO persistent volume + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". type: string gateway: - description: The host address of the ScaleIO API Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef references to the secret for + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. properties: @@ -11886,26 +12747,26 @@ spec: type: string type: object sslEnabled: - description: Flag to enable/disable SSL communication + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false type: boolean storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. type: string storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. type: string system: - description: The name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system + as configured in ScaleIO. type: string volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. type: string required: - gateway @@ -11913,57 +12774,58 @@ spec: - system type: object secret: - description: 'Secret represents a secret that should populate + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -11971,30 +12833,30 @@ spec: type: object type: array optional: - description: Specify whether the Secret or its keys - must be defined + description: optional field specify whether the Secret + or its keys must be defined type: boolean secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' type: string type: object storageos: - description: StorageOS represents a StorageOS volume attached + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef specifies the secret to use for + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. properties: @@ -12005,12 +12867,12 @@ spec: type: string type: object volumeName: - description: VolumeName is the human-readable name of + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. type: string volumeNamespace: - description: VolumeNamespace specifies the scope of + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within @@ -12022,25 +12884,26 @@ spec: type: string type: object vsphereVolume: - description: VsphereVolume represents a vSphere volume attached + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. type: string volumePath: - description: Path that identifies vSphere volume vmdk + description: volumePath is the path that identifies + vSphere volume vmdk type: string required: - volumePath @@ -12154,8 +13017,9 @@ spec: for the Argo CD Server component. properties: maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. format: int32 type: integer minReplicas: @@ -12174,23 +13038,26 @@ spec: Scale subresource. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the + referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. format: int32 type: integer required: @@ -12354,12 +13221,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -12367,13 +13234,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -12412,10 +13279,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -12425,13 +13292,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -12461,6 +13328,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Argo CD server component. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12481,7 +13370,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -12601,6 +13491,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12622,7 +13534,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -12640,6 +13552,28 @@ spec: description: Resources defines the Compute Resources required by the container for Keycloak. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12661,7 +13595,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object rootCA: diff --git a/config/crd/bases/argoproj.io_argocdexports.yaml b/config/crd/bases/argoproj.io_argocdexports.yaml index 1ac7a92dd..9061faa25 100644 --- a/config/crd/bases/argoproj.io_argocdexports.yaml +++ b/config/crd/bases/argoproj.io_argocdexports.yaml @@ -56,20 +56,23 @@ spec: description: PVC is the desired characteristics for a PersistentVolumeClaim. properties: accessModes: - description: 'AccessModes contains the desired access modes + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify either: * - An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + description: 'dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always have the - same contents as the DataSourceRef field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will be copied + to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not + be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the resource being @@ -88,26 +91,32 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which to populate - the volume with data, if a non-empty volume is desired. - This may be any local object from a non-empty API group - (non core object) or a PersistentVolumeClaim object. When - this field is specified, volume binding will only succeed + description: 'dataSourceRef specifies the object from which + to populate the volume with data, if a non-empty volume + is desired. This may be any object from a non-empty API + group (non core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will - replace the functionality of the DataSource field and as + replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same - value. For backwards compatibility, both fields (DataSource - and DataSourceRef) will be set to the same value automatically - if one of them is empty and the other is non-empty. There - are two important differences between DataSource and DataSourceRef: - * While DataSource only allows two specific types of objects, - DataSourceRef allows any non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed values (dropping - them), DataSourceRef preserves all values, and generates - an error if a disallowed value is specified. (Alpha) Using - this field requires the AnyVolumeDataSource feature gate - to be enabled.' + value. For backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource and + dataSourceRef) will be set to the same value automatically + if one of them is empty and the other is non-empty. When + namespace is specified in dataSourceRef, dataSource isn''t + set to the same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, + dataSourceRef allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and generates + an error if a disallowed value is specified. * While dataSource + only allows local objects, dataSourceRef allows objects in + any namespaces. (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the resource being @@ -121,18 +130,50 @@ spec: name: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace of resource being + referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object is + required in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource feature gate to be + enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum resources the + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -154,11 +195,12 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider for binding. + description: selector is a label query over volumes to consider + for binding. properties: matchExpressions: description: matchExpressions is a list of label selector @@ -203,8 +245,8 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of volume is required @@ -212,7 +254,7 @@ spec: in claim spec. type: string volumeName: - description: VolumeName is the binding reference to the PersistentVolume + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index c00bc7677..51f836e37 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -180,6 +180,28 @@ spec: description: Resources defines the Compute Resources required by the container for ApplicationSet. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -200,7 +222,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -243,12 +266,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -256,13 +279,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -516,6 +539,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Application Controller. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -536,7 +581,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sharding: @@ -599,6 +645,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -619,7 +687,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -687,10 +756,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -700,13 +769,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -717,6 +786,28 @@ spec: description: Resources defines the Compute Resources required by the container for Grafana. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -737,7 +828,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -841,6 +933,28 @@ spec: description: Resources defines the Compute Resources required by the container for HA. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -861,7 +975,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object required: @@ -1130,6 +1245,28 @@ spec: description: Resources defines the Compute Resources required by the container for Argo CD Notifications. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -1150,7 +1287,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -1202,10 +1340,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -1215,13 +1353,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -1354,6 +1492,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -1374,7 +1534,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -1525,11 +1686,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -1540,7 +1701,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -1716,7 +1877,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -1771,7 +1932,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -1870,7 +2034,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -1952,8 +2119,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -1985,7 +2151,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2082,13 +2250,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -2160,8 +2328,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -2193,7 +2360,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2283,10 +2452,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -2308,9 +2521,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -2435,7 +2669,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -2468,15 +2703,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2525,8 +2756,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -2558,7 +2788,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2786,6 +3018,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -2806,7 +3060,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object serviceaccount: @@ -2821,11 +3076,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -2836,7 +3091,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -3012,7 +3267,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -3067,7 +3322,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -3166,7 +3424,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -3248,8 +3509,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3281,7 +3541,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -3378,13 +3640,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -3456,8 +3718,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3489,7 +3750,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -3579,10 +3842,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -3604,9 +3911,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -3731,7 +4059,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -3764,15 +4093,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -3821,8 +4146,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3854,7 +4178,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -4115,122 +4441,124 @@ spec: may be accessed by any container in the pod. properties: awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' format: int32 type: integer readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: boolean volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: string required: - volumeID type: object azureDisk: - description: AzureDisk represents an Azure Data Disk mount + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. properties: cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' type: string diskName: - description: The Name of the data disk in the blob storage + description: diskName is the Name of the data disk in + the blob storage type: string diskURI: - description: The URI the data disk in the blob storage + description: diskURI is the URI of data disk in the + blob storage type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults to shared' type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean required: - diskName - diskURI type: object azureFile: - description: AzureFile represents an Azure File Service + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. properties: readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretName: - description: the name of secret that contains Azure - Storage Account Name and Key + description: secretName is the name of secret that + contains Azure Storage Account Name and Key type: string shareName: - description: Share Name + description: shareName is the azure share Name type: string required: - secretName - shareName type: object cephfs: - description: CephFS represents a Ceph FS mount on the host + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime properties: monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' items: type: string type: array path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' type: string readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: boolean secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4239,30 +4567,30 @@ spec: type: string type: object user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string required: - monitors type: object cinder: - description: 'Cinder represents a cinder volume attached + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string readOnly: - description: 'Optional: Defaults to false (read/write). + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: boolean secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4271,37 +4599,38 @@ spec: type: string type: object volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string required: - volumeID type: object configMap: - description: ConfigMap represents a configMap that should + description: configMap represents a configMap that should populate this volume properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: @@ -4309,26 +4638,26 @@ spec: volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -4340,28 +4669,28 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: - description: Specify whether the ConfigMap or its keys - must be defined + description: optional specify whether the ConfigMap + or its keys must be defined type: boolean type: object csi: - description: CSI (Container Storage Interface) represents + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). properties: driver: - description: Driver is the name of the CSI driver that + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. type: string fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. type: string nodePublishSecretRef: - description: NodePublishSecretRef is a reference to + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, @@ -4376,13 +4705,13 @@ spec: type: string type: object readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). type: boolean volumeAttributes: additionalProperties: type: string - description: VolumeAttributes stores driver-specific + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. type: object @@ -4390,7 +4719,7 @@ spec: - driver type: object downwardAPI: - description: DownwardAPI represents downward API about the + description: downwardAPI represents downward API about the pod that should populate this volume properties: defaultMode: @@ -4480,31 +4809,33 @@ spec: type: array type: object emptyDir: - description: 'EmptyDir represents a temporary directory + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' properties: medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' type: string sizeLimit: anyOf: - type: integer - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object ephemeral: - description: "Ephemeral represents a volume that is handled + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n @@ -4560,24 +4891,27 @@ spec: also valid here. properties: accessModes: - description: 'AccessModes contains the desired + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the @@ -4599,32 +4933,41 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the @@ -4641,12 +4984,23 @@ spec: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than @@ -4654,6 +5008,32 @@ spec: capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -4677,12 +5057,13 @@ spec: If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider - for binding. + description: selector is a label query over + volumes to consider for binding. properties: matchExpressions: description: matchExpressions is a list @@ -4733,8 +5114,9 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of @@ -4743,7 +5125,7 @@ spec: claim spec. type: string volumeName: - description: VolumeName is the binding reference + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object @@ -4752,32 +5134,34 @@ spec: type: object type: object fc: - description: FC represents a Fibre Channel resource that + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' type: string lun: - description: 'Optional: FC target lun number' + description: 'lun is Optional: FC target lun number' format: int32 type: integer readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' items: type: string type: array wwids: - description: 'Optional: FC volume world wide identifiers + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' items: @@ -4785,35 +5169,37 @@ spec: type: array type: object flexVolume: - description: FlexVolume represents a generic volume resource + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. properties: driver: - description: Driver is the name of the driver to use + description: driver is the name of the driver to use for this volume. type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. type: string options: additionalProperties: type: string - description: 'Optional: Extra command options if any.' + description: 'options is Optional: this field holds + extra command options if any.' type: object readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4825,49 +5211,50 @@ spec: - driver type: object flocker: - description: Flocker represents a Flocker volume attached + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated type: string datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset type: string type: object gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' format: int32 type: integer pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: boolean @@ -4875,42 +5262,43 @@ spec: - pdName type: object gitRepo: - description: 'GitRepo represents a git repository at a particular + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' properties: directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. type: string repository: - description: Repository URL + description: repository is the URL type: string revision: - description: Commit hash for the specified revision. + description: revision is the commit hash for the specified + revision. type: string required: - repository type: object glusterfs: - description: 'Glusterfs represents a Glusterfs mount on + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' properties: endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string path: - description: 'Path is the Glusterfs volume path. More + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string readOnly: - description: 'ReadOnly here will force the Glusterfs + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: boolean @@ -4919,7 +5307,7 @@ spec: - path type: object hostPath: - description: 'HostPath represents a pre-existing file or + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the @@ -4930,68 +5318,71 @@ spec: as read/write.' properties: path: - description: 'Path of the directory on the host. If + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string type: - description: 'Type for HostPath Volume Defaults to "" + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string required: - path type: object iscsi: - description: 'ISCSI represents an ISCSI Disk resource that + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' properties: chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication type: boolean chapAuthSession: - description: whether support iSCSI Session CHAP authentication + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication type: boolean fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' type: string initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. type: string iqn: - description: Target iSCSI Qualified Name. + description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). type: string lun: - description: iSCSI Target Lun number. + description: lun represents iSCSI Target Lun number. format: int32 type: integer portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). items: type: string type: array readOnly: - description: ReadOnly here will force the ReadOnly setting + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. type: boolean secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -5000,9 +5391,10 @@ spec: type: string type: object targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). type: string required: - iqn @@ -5010,24 +5402,24 @@ spec: - targetPortal type: object name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string nfs: - description: 'NFS represents an NFS mount on the host that + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' properties: path: - description: 'Path that is exported by the NFS server. + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string readOnly: - description: 'ReadOnly here will force the NFS export + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: boolean server: - description: 'Server is the hostname or IP address of + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string required: @@ -5035,89 +5427,89 @@ spec: - server type: object persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' properties: claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' type: string readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. type: boolean required: - claimName type: object photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string pdID: - description: ID that identifies Photon Controller persistent - disk + description: pdID is the ID that identifies Photon Controller + persistent disk type: string required: - pdID type: object portworxVolume: - description: PortworxVolume represents a portworx volume + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine properties: fsType: - description: FSType represents the filesystem type to + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean volumeID: - description: VolumeID uniquely identifies a Portworx + description: volumeID uniquely identifies a Portworx volume type: string required: - volumeID type: object projected: - description: Items for all in one resources secrets, configmaps, - and downward API + description: projected items for all in one resources secrets, + configmaps, and downward API properties: defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. format: int32 type: integer sources: - description: list of volume projections + description: sources is the list of volume projections items: description: Projection that may be projected along with other supported volume types properties: configMap: - description: information about the configMap data - to project + description: configMap information about the configMap + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content @@ -5134,27 +5526,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -5170,13 +5562,13 @@ spec: kind, uid?' type: string optional: - description: Specify whether the ConfigMap - or its keys must be defined + description: optional specify whether the + ConfigMap or its keys must be defined type: boolean type: object downwardAPI: - description: information about the downwardAPI - data to project + description: downwardAPI information about the + downwardAPI data to project properties: items: description: Items is a list of DownwardAPIVolume @@ -5260,11 +5652,11 @@ spec: type: array type: object secret: - description: information about the secret data - to project + description: secret information about the secret + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content @@ -5281,27 +5673,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -5317,16 +5709,16 @@ spec: kind, uid?' type: string optional: - description: Specify whether the Secret or - its key must be defined + description: optional field specify whether + the Secret or its key must be defined type: boolean type: object serviceAccountToken: - description: information about the serviceAccountToken - data to project + description: serviceAccountToken is information + about the serviceAccountToken data to project properties: audience: - description: Audience is the intended audience + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise @@ -5334,7 +5726,7 @@ spec: to the identifier of the apiserver. type: string expirationSeconds: - description: ExpirationSeconds is the requested + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively @@ -5347,7 +5739,7 @@ spec: format: int64 type: integer path: - description: Path is the path relative to + description: path is the path relative to the mount point of the file to project the token into. type: string @@ -5358,35 +5750,35 @@ spec: type: array type: object quobyte: - description: Quobyte represents a Quobyte mount on the host + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime properties: group: - description: Group to map volume access to Default is + description: group to map volume access to Default is no group type: string readOnly: - description: ReadOnly here will force the Quobyte volume + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. type: boolean registry: - description: Registry represents a single or multiple + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes type: string tenant: - description: Tenant owning the given Quobyte volume + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin type: string user: - description: User to map volume access to Defaults to + description: user to map volume access to Defaults to serivceaccount user type: string volume: - description: Volume is a string that references an already + description: volume is a string that references an already created Quobyte volume by name. type: string required: @@ -5394,43 +5786,44 @@ spec: - volume type: object rbd: - description: 'RBD represents a Rados Block Device mount + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' type: string image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string keyring: - description: 'Keyring is the path to key ring for RBDUser. + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' items: type: string type: array pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: boolean secretRef: - description: 'SecretRef is name of the authentication + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' properties: @@ -5441,35 +5834,36 @@ spec: type: string type: object user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string required: - image - monitors type: object scaleIO: - description: ScaleIO represents a ScaleIO persistent volume + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". type: string gateway: - description: The host address of the ScaleIO API Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef references to the secret for + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. properties: @@ -5480,26 +5874,26 @@ spec: type: string type: object sslEnabled: - description: Flag to enable/disable SSL communication + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false type: boolean storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. type: string storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. type: string system: - description: The name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system + as configured in ScaleIO. type: string volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. type: string required: - gateway @@ -5507,57 +5901,58 @@ spec: - system type: object secret: - description: 'Secret represents a secret that should populate + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -5565,30 +5960,30 @@ spec: type: object type: array optional: - description: Specify whether the Secret or its keys - must be defined + description: optional field specify whether the Secret + or its keys must be defined type: boolean secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' type: string type: object storageos: - description: StorageOS represents a StorageOS volume attached + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef specifies the secret to use for + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. properties: @@ -5599,12 +5994,12 @@ spec: type: string type: object volumeName: - description: VolumeName is the human-readable name of + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. type: string volumeNamespace: - description: VolumeNamespace specifies the scope of + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within @@ -5616,25 +6011,26 @@ spec: type: string type: object vsphereVolume: - description: VsphereVolume represents a vSphere volume attached + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. type: string volumePath: - description: Path that identifies vSphere volume vmdk + description: volumePath is the path that identifies + vSphere volume vmdk type: string required: - volumePath @@ -5755,8 +6151,9 @@ spec: for the Argo CD Server component. properties: maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. format: int32 type: integer minReplicas: @@ -5775,23 +6172,26 @@ spec: Scale subresource. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the + referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. format: int32 type: integer required: @@ -5955,12 +6355,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5968,13 +6368,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -6013,10 +6413,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -6026,13 +6426,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -6062,6 +6462,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Argo CD server component. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6082,7 +6504,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -6202,6 +6625,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6223,7 +6668,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -6245,6 +6690,28 @@ spec: description: Resources defines the Compute Resources required by the container for Keycloak. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6266,7 +6733,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object rootCA: @@ -6289,6 +6756,28 @@ spec: Resources defines the Compute Resources required by the container for SSO. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6309,7 +6798,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object verifyTLS: @@ -6623,6 +7113,28 @@ spec: description: Resources defines the Compute Resources required by the container for ApplicationSet. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6643,7 +7155,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object scmRootCAConfigMap: @@ -6691,12 +7204,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -6704,13 +7217,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -6964,6 +7477,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Application Controller. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6984,7 +7519,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sharding: @@ -7084,10 +7620,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -7097,13 +7633,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -7114,6 +7650,28 @@ spec: description: Resources defines the Compute Resources required by the container for Grafana. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7134,7 +7692,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -7238,6 +7797,28 @@ spec: description: Resources defines the Compute Resources required by the container for HA. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7258,7 +7839,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object required: @@ -7527,6 +8109,28 @@ spec: description: Resources defines the Compute Resources required by the container for Argo CD Notifications. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7547,7 +8151,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -7599,10 +8204,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -7612,13 +8217,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -7751,6 +8356,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7771,7 +8398,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -7922,11 +8550,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -7937,7 +8565,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -8113,7 +8741,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -8168,7 +8796,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -8267,7 +8898,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -8349,8 +8983,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8382,7 +9015,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -8479,13 +9114,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -8557,8 +9192,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8590,7 +9224,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -8680,10 +9316,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -8705,9 +9385,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -8832,7 +9533,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -8865,15 +9567,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -8922,8 +9620,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8955,7 +9652,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9183,6 +9882,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -9203,7 +9924,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object serviceaccount: @@ -9218,11 +9940,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -9233,7 +9955,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -9409,7 +10131,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -9464,7 +10186,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -9563,7 +10288,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -9645,8 +10373,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -9678,7 +10405,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9775,13 +10504,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -9853,8 +10582,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -9886,7 +10614,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9976,10 +10706,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -10001,9 +10775,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -10128,7 +10923,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -10161,15 +10957,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -10218,8 +11010,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -10251,7 +11042,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -10512,122 +11305,124 @@ spec: may be accessed by any container in the pod. properties: awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' format: int32 type: integer readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: boolean volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: string required: - volumeID type: object azureDisk: - description: AzureDisk represents an Azure Data Disk mount + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. properties: cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' type: string diskName: - description: The Name of the data disk in the blob storage + description: diskName is the Name of the data disk in + the blob storage type: string diskURI: - description: The URI the data disk in the blob storage + description: diskURI is the URI of data disk in the + blob storage type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults to shared' type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean required: - diskName - diskURI type: object azureFile: - description: AzureFile represents an Azure File Service + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. properties: readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretName: - description: the name of secret that contains Azure - Storage Account Name and Key + description: secretName is the name of secret that + contains Azure Storage Account Name and Key type: string shareName: - description: Share Name + description: shareName is the azure share Name type: string required: - secretName - shareName type: object cephfs: - description: CephFS represents a Ceph FS mount on the host + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime properties: monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' items: type: string type: array path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' type: string readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: boolean secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -10636,30 +11431,30 @@ spec: type: string type: object user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string required: - monitors type: object cinder: - description: 'Cinder represents a cinder volume attached + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string readOnly: - description: 'Optional: Defaults to false (read/write). + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: boolean secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -10668,37 +11463,38 @@ spec: type: string type: object volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string required: - volumeID type: object configMap: - description: ConfigMap represents a configMap that should + description: configMap represents a configMap that should populate this volume properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: @@ -10706,26 +11502,26 @@ spec: volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -10737,28 +11533,28 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: - description: Specify whether the ConfigMap or its keys - must be defined + description: optional specify whether the ConfigMap + or its keys must be defined type: boolean type: object csi: - description: CSI (Container Storage Interface) represents + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). properties: driver: - description: Driver is the name of the CSI driver that + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. type: string fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. type: string nodePublishSecretRef: - description: NodePublishSecretRef is a reference to + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, @@ -10773,13 +11569,13 @@ spec: type: string type: object readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). type: boolean volumeAttributes: additionalProperties: type: string - description: VolumeAttributes stores driver-specific + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. type: object @@ -10787,7 +11583,7 @@ spec: - driver type: object downwardAPI: - description: DownwardAPI represents downward API about the + description: downwardAPI represents downward API about the pod that should populate this volume properties: defaultMode: @@ -10877,31 +11673,33 @@ spec: type: array type: object emptyDir: - description: 'EmptyDir represents a temporary directory + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' properties: medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' type: string sizeLimit: anyOf: - type: integer - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object ephemeral: - description: "Ephemeral represents a volume that is handled + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n @@ -10957,24 +11755,27 @@ spec: also valid here. properties: accessModes: - description: 'AccessModes contains the desired + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the @@ -10996,32 +11797,41 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the @@ -11038,12 +11848,23 @@ spec: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than @@ -11051,6 +11872,32 @@ spec: capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -11074,12 +11921,13 @@ spec: If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider - for binding. + description: selector is a label query over + volumes to consider for binding. properties: matchExpressions: description: matchExpressions is a list @@ -11130,8 +11978,9 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of @@ -11140,7 +11989,7 @@ spec: claim spec. type: string volumeName: - description: VolumeName is the binding reference + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object @@ -11149,32 +11998,34 @@ spec: type: object type: object fc: - description: FC represents a Fibre Channel resource that + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' type: string lun: - description: 'Optional: FC target lun number' + description: 'lun is Optional: FC target lun number' format: int32 type: integer readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' items: type: string type: array wwids: - description: 'Optional: FC volume world wide identifiers + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' items: @@ -11182,35 +12033,37 @@ spec: type: array type: object flexVolume: - description: FlexVolume represents a generic volume resource + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. properties: driver: - description: Driver is the name of the driver to use + description: driver is the name of the driver to use for this volume. type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. type: string options: additionalProperties: type: string - description: 'Optional: Extra command options if any.' + description: 'options is Optional: this field holds + extra command options if any.' type: object readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -11222,49 +12075,50 @@ spec: - driver type: object flocker: - description: Flocker represents a Flocker volume attached + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated type: string datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset type: string type: object gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' format: int32 type: integer pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: boolean @@ -11272,42 +12126,43 @@ spec: - pdName type: object gitRepo: - description: 'GitRepo represents a git repository at a particular + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' properties: directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. type: string repository: - description: Repository URL + description: repository is the URL type: string revision: - description: Commit hash for the specified revision. + description: revision is the commit hash for the specified + revision. type: string required: - repository type: object glusterfs: - description: 'Glusterfs represents a Glusterfs mount on + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' properties: endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string path: - description: 'Path is the Glusterfs volume path. More + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string readOnly: - description: 'ReadOnly here will force the Glusterfs + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: boolean @@ -11316,7 +12171,7 @@ spec: - path type: object hostPath: - description: 'HostPath represents a pre-existing file or + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the @@ -11327,68 +12182,71 @@ spec: as read/write.' properties: path: - description: 'Path of the directory on the host. If + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string type: - description: 'Type for HostPath Volume Defaults to "" + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string required: - path type: object iscsi: - description: 'ISCSI represents an ISCSI Disk resource that + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' properties: chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication type: boolean chapAuthSession: - description: whether support iSCSI Session CHAP authentication + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication type: boolean fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' type: string initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. type: string iqn: - description: Target iSCSI Qualified Name. + description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). type: string lun: - description: iSCSI Target Lun number. + description: lun represents iSCSI Target Lun number. format: int32 type: integer portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). items: type: string type: array readOnly: - description: ReadOnly here will force the ReadOnly setting + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. type: boolean secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -11397,9 +12255,10 @@ spec: type: string type: object targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). type: string required: - iqn @@ -11407,24 +12266,24 @@ spec: - targetPortal type: object name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string nfs: - description: 'NFS represents an NFS mount on the host that + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' properties: path: - description: 'Path that is exported by the NFS server. + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string readOnly: - description: 'ReadOnly here will force the NFS export + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: boolean server: - description: 'Server is the hostname or IP address of + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string required: @@ -11432,89 +12291,89 @@ spec: - server type: object persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' properties: claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' type: string readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. type: boolean required: - claimName type: object photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string pdID: - description: ID that identifies Photon Controller persistent - disk + description: pdID is the ID that identifies Photon Controller + persistent disk type: string required: - pdID type: object portworxVolume: - description: PortworxVolume represents a portworx volume + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine properties: fsType: - description: FSType represents the filesystem type to + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean volumeID: - description: VolumeID uniquely identifies a Portworx + description: volumeID uniquely identifies a Portworx volume type: string required: - volumeID type: object projected: - description: Items for all in one resources secrets, configmaps, - and downward API + description: projected items for all in one resources secrets, + configmaps, and downward API properties: defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. format: int32 type: integer sources: - description: list of volume projections + description: sources is the list of volume projections items: description: Projection that may be projected along with other supported volume types properties: configMap: - description: information about the configMap data - to project + description: configMap information about the configMap + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content @@ -11531,27 +12390,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -11567,13 +12426,13 @@ spec: kind, uid?' type: string optional: - description: Specify whether the ConfigMap - or its keys must be defined + description: optional specify whether the + ConfigMap or its keys must be defined type: boolean type: object downwardAPI: - description: information about the downwardAPI - data to project + description: downwardAPI information about the + downwardAPI data to project properties: items: description: Items is a list of DownwardAPIVolume @@ -11657,11 +12516,11 @@ spec: type: array type: object secret: - description: information about the secret data - to project + description: secret information about the secret + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content @@ -11678,27 +12537,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -11714,16 +12573,16 @@ spec: kind, uid?' type: string optional: - description: Specify whether the Secret or - its key must be defined + description: optional field specify whether + the Secret or its key must be defined type: boolean type: object serviceAccountToken: - description: information about the serviceAccountToken - data to project + description: serviceAccountToken is information + about the serviceAccountToken data to project properties: audience: - description: Audience is the intended audience + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise @@ -11731,7 +12590,7 @@ spec: to the identifier of the apiserver. type: string expirationSeconds: - description: ExpirationSeconds is the requested + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively @@ -11744,7 +12603,7 @@ spec: format: int64 type: integer path: - description: Path is the path relative to + description: path is the path relative to the mount point of the file to project the token into. type: string @@ -11755,35 +12614,35 @@ spec: type: array type: object quobyte: - description: Quobyte represents a Quobyte mount on the host + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime properties: group: - description: Group to map volume access to Default is + description: group to map volume access to Default is no group type: string readOnly: - description: ReadOnly here will force the Quobyte volume + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. type: boolean registry: - description: Registry represents a single or multiple + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes type: string tenant: - description: Tenant owning the given Quobyte volume + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin type: string user: - description: User to map volume access to Defaults to + description: user to map volume access to Defaults to serivceaccount user type: string volume: - description: Volume is a string that references an already + description: volume is a string that references an already created Quobyte volume by name. type: string required: @@ -11791,43 +12650,44 @@ spec: - volume type: object rbd: - description: 'RBD represents a Rados Block Device mount + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' type: string image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string keyring: - description: 'Keyring is the path to key ring for RBDUser. + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' items: type: string type: array pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: boolean secretRef: - description: 'SecretRef is name of the authentication + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' properties: @@ -11838,35 +12698,36 @@ spec: type: string type: object user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string required: - image - monitors type: object scaleIO: - description: ScaleIO represents a ScaleIO persistent volume + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". type: string gateway: - description: The host address of the ScaleIO API Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef references to the secret for + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. properties: @@ -11877,26 +12738,26 @@ spec: type: string type: object sslEnabled: - description: Flag to enable/disable SSL communication + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false type: boolean storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. type: string storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. type: string system: - description: The name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system + as configured in ScaleIO. type: string volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. type: string required: - gateway @@ -11904,57 +12765,58 @@ spec: - system type: object secret: - description: 'Secret represents a secret that should populate + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -11962,30 +12824,30 @@ spec: type: object type: array optional: - description: Specify whether the Secret or its keys - must be defined + description: optional field specify whether the Secret + or its keys must be defined type: boolean secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' type: string type: object storageos: - description: StorageOS represents a StorageOS volume attached + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef specifies the secret to use for + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. properties: @@ -11996,12 +12858,12 @@ spec: type: string type: object volumeName: - description: VolumeName is the human-readable name of + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. type: string volumeNamespace: - description: VolumeNamespace specifies the scope of + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within @@ -12013,25 +12875,26 @@ spec: type: string type: object vsphereVolume: - description: VsphereVolume represents a vSphere volume attached + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. type: string volumePath: - description: Path that identifies vSphere volume vmdk + description: volumePath is the path that identifies + vSphere volume vmdk type: string required: - volumePath @@ -12145,8 +13008,9 @@ spec: for the Argo CD Server component. properties: maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. format: int32 type: integer minReplicas: @@ -12165,23 +13029,26 @@ spec: Scale subresource. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the + referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. format: int32 type: integer required: @@ -12345,12 +13212,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -12358,13 +13225,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -12403,10 +13270,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -12416,13 +13283,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -12452,6 +13319,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Argo CD server component. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12472,7 +13361,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -12592,6 +13482,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12613,7 +13525,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -12631,6 +13543,28 @@ spec: description: Resources defines the Compute Resources required by the container for Keycloak. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12652,7 +13586,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object rootCA: diff --git a/controllers/argocd/applicationset_test.go b/controllers/argocd/applicationset_test.go index 9a7022baf..b022e4cad 100644 --- a/controllers/argocd/applicationset_test.go +++ b/controllers/argocd/applicationset_test.go @@ -77,7 +77,12 @@ func TestReconcileApplicationSet_CreateDeployments(t *testing.T) { a := makeTestArgoCD() a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} @@ -188,7 +193,12 @@ func TestReconcileApplicationSetProxyConfiguration(t *testing.T) { a := makeTestArgoCD() a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} @@ -258,8 +268,12 @@ func TestReconcileApplicationSet_UpdateExistingDeployments(t *testing.T) { }, } - runtimeObjs := []runtime.Object{a, existingDeployment} - r := makeTestReconciler(t, runtimeObjs...) + resObjs := []client.Object{a, existingDeployment} + subresObjs := []client.Object{a, existingDeployment} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} @@ -283,7 +297,12 @@ func TestReconcileApplicationSet_Deployments_resourceRequirements(t *testing.T) logf.SetLogger(ZapLogger(true)) a := makeTestArgoCDWithResources() - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} @@ -378,7 +397,12 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { } a := makeTestArgoCD() - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) cm := newConfigMapWithName(getCAConfigMapName(a), a) r.Client.Create(context.Background(), cm, &client.CreateOptions{}) @@ -407,7 +431,12 @@ func TestReconcileApplicationSet_Deployments_SpecOverride(t *testing.T) { func TestReconcileApplicationSet_ServiceAccount(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) retSa, err := r.reconcileApplicationSetServiceAccount(a) assert.NoError(t, err) @@ -429,7 +458,13 @@ func TestReconcileApplicationSet_ServiceAccount(t *testing.T) { func TestReconcileApplicationSet_Role(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) roleRet, err := r.reconcileApplicationSetRole(a) assert.NoError(t, err) @@ -475,7 +510,13 @@ func TestReconcileApplicationSet_Role(t *testing.T) { func TestReconcileApplicationSet_RoleBinding(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) role := &rbacv1.Role{ObjectMeta: metav1.ObjectMeta{Name: "role-name"}} sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "sa-name"}} @@ -514,7 +555,13 @@ func setProxyEnvVars(t *testing.T) { func TestReconcileApplicationSet_Service(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) s := newServiceWithSuffix(common.ApplicationSetServiceNameSuffix, common.ApplicationSetServiceNameSuffix, a) @@ -525,7 +572,13 @@ func TestReconcileApplicationSet_Service(t *testing.T) { func TestArgoCDApplicationSetCommand(t *testing.T) { a := makeTestArgoCD() a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) baseCommand := []string{ "entrypoint.sh", @@ -612,7 +665,13 @@ func TestArgoCDApplicationSetCommand(t *testing.T) { func TestArgoCDApplicationSetEnv(t *testing.T) { a := makeTestArgoCD() a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) defaultEnv := []corev1.EnvVar{ { diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 096649c02..203616783 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -175,9 +175,7 @@ func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) ( // remove namespace of deleted Argo CD instance from deprecationEventEmissionTracker (if exists) so that if another instance // is created in the same namespace in the future, that instance is appropriately tracked - if _, ok := DeprecationEventEmissionTracker[argocd.Namespace]; ok { - delete(DeprecationEventEmissionTracker, argocd.Namespace) - } + delete(DeprecationEventEmissionTracker, argocd.Namespace) } return reconcile.Result{}, nil } diff --git a/controllers/argocd/argocd_controller_test.go b/controllers/argocd/argocd_controller_test.go index 292bcf361..0b105c65f 100644 --- a/controllers/argocd/argocd_controller_test.go +++ b/controllers/argocd/argocd_controller_test.go @@ -49,7 +49,13 @@ func TestReconcileArgoCD_Reconcile_with_deleted(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD(deletedAt(time.Now())) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) req := reconcile.Request{ @@ -77,7 +83,13 @@ func TestReconcileArgoCD_Reconcile(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) req := reconcile.Request{ @@ -116,7 +128,14 @@ func TestReconcileArgoCD_LabelSelector(t *testing.T) { c := makeTestArgoCD(func(ac *argoproj.ArgoCD) { ac.Name = "argo-test-3" }) - rt := makeTestReconciler(t, a, b, c) + + resObjs := []client.Object{a, b, c} + subresObjs := []client.Object{a, b, c} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + rt := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(rt, a.Namespace, "")) // All ArgoCD instances should be reconciled if no label-selctor is applied to the operator. @@ -226,7 +245,13 @@ func TestReconcileArgoCD_Reconcile_RemoveManagedByLabelOnArgocdDeletion(t *testi for _, test := range tests { t.Run(test.testName, func(t *testing.T) { a := makeTestArgoCD(deletedAt(time.Now()), addFinalizer(common.ArgoCDDeletionFinalizer)) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) nsArgocd := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{ Name: a.Namespace, @@ -275,6 +300,7 @@ func deletedAt(now time.Time) argoCDOpt { return func(a *argoproj.ArgoCD) { wrapped := metav1.NewTime(now) a.ObjectMeta.DeletionTimestamp = &wrapped + a.Finalizers = []string{"test: finalizaer"} } } @@ -282,9 +308,15 @@ func TestReconcileArgoCD_CleanUp(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD(deletedAt(time.Now()), addFinalizer(common.ArgoCDDeletionFinalizer)) - resources := []runtime.Object{a} + resources := []client.Object{a} resources = append(resources, clusterResources(a)...) - r := makeTestReconciler(t, resources...) + + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resources, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) req := reconcile.Request{ @@ -344,8 +376,8 @@ func addFinalizer(finalizer string) argoCDOpt { } } -func clusterResources(argocd *argoproj.ArgoCD) []runtime.Object { - return []runtime.Object{ +func clusterResources(argocd *argoproj.ArgoCD) []client.Object { + return []client.Object{ newClusterRole(common.ArgoCDApplicationControllerComponent, []v1.PolicyRule{}, argocd), newClusterRole(common.ArgoCDServerComponent, []v1.PolicyRule{}, argocd), newClusterRoleBindingWithname(common.ArgoCDApplicationControllerComponent, argocd), diff --git a/controllers/argocd/configmap.go b/controllers/argocd/configmap.go index 1456ec4e0..0c5d11dde 100644 --- a/controllers/argocd/configmap.go +++ b/controllers/argocd/configmap.go @@ -17,7 +17,7 @@ package argocd import ( "context" "fmt" - "io/ioutil" + "os" "path/filepath" "reflect" "strings" @@ -548,7 +548,7 @@ func (r *ReconcileArgoCD) reconcileGrafanaDashboards(cr *argoproj.ArgoCD) error data := make(map[string]string) for _, f := range dashboards { - dashboard, err := ioutil.ReadFile(f) + dashboard, err := os.ReadFile(f) if err != nil { return err } diff --git a/controllers/argocd/configmap_test.go b/controllers/argocd/configmap_test.go index 7dee383a7..a4bae2798 100644 --- a/controllers/argocd/configmap_test.go +++ b/controllers/argocd/configmap_test.go @@ -25,7 +25,9 @@ import ( "gopkg.in/yaml.v2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -39,7 +41,13 @@ var _ reconcile.Reconciler = &ReconcileArgoCD{} func TestReconcileArgoCD_reconcileTLSCerts(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD(initialCerts(t, "root-ca.example.com")) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileTLSCerts(a)) @@ -61,7 +69,13 @@ func TestReconcileArgoCD_reconcileTLSCerts(t *testing.T) { func TestReconcileArgoCD_reconcileTLSCerts_configMapUpdate(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD(initialCerts(t, "root-ca.example.com")) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileTLSCerts(a)) @@ -98,7 +112,14 @@ func TestReconcileArgoCD_reconcileTLSCerts_configMapUpdate(t *testing.T) { func TestReconcileArgoCD_reconcileTLSCerts_withInitialCertsUpdate(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, r.reconcileTLSCerts(a)) a = makeTestArgoCD(initialCerts(t, "testing.example.com")) @@ -187,7 +208,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap(t *testing.T) { a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: argoproj.SSOProviderTypeDex, } - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -210,7 +237,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap(t *testing.T) { func TestReconcileArgoCD_reconcileEmptyArgoConfigMap(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) // An empty Argo CD Configmap emptyArgoConfigmap := &corev1.ConfigMap{ @@ -256,7 +289,13 @@ func TestReconcileArgoCDCM_withRepoCredentials(t *testing.T) { "admin.enabled": "true", }, } - r := makeTestReconciler(t, a, cm) + + resObjs := []client.Object{a, cm} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -277,7 +316,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withDisableAdmin(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.DisableAdmin = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -334,7 +379,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withDexConnector(t *testing.T) { }) secret := argoutil.NewSecretWithName(a, "token") - r := makeTestReconciler(t, a, sa, secret) + + resObjs := []client.Object{a, sa, secret} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) if test.updateCrSpecFunc != nil { test.updateCrSpecFunc(a) @@ -395,7 +446,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withDexDisabled(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(test.argoCD) assert.NoError(t, err) @@ -469,7 +526,12 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_dexConfigDeletedwhenDexDisabled( } secret := argoutil.NewSecretWithName(test.argoCD, "token") - r := makeTestReconciler(t, test.argoCD, sa, secret) + resObjs := []client.Object{test.argoCD, sa, secret} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(test.argoCD) assert.NoError(t, err) @@ -518,7 +580,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withKustomizeVersions(t *testing kvs = append(kvs, kv) a.Spec.KustomizeVersions = kvs }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -540,7 +608,13 @@ func TestReconcileArgoCD_reconcileGPGKeysConfigMap(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.DisableAdmin = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileGPGKeysConfigMap(a) assert.NoError(t, err) @@ -557,7 +631,13 @@ func TestReconcileArgoCD_reconcileGPGKeysConfigMap(t *testing.T) { func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceTrackingMethod(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -647,7 +727,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withResourceInclusions(t *testin a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.ResourceInclusions = customizations }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -761,7 +847,13 @@ managedfieldsmanagers: a.Spec.ResourceActions = actions a.Spec.ResourceIgnoreDifferences = &ignoreDifferences }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -793,7 +885,13 @@ managedfieldsmanagers: func TestReconcileArgoCD_reconcileArgoConfigMap_withExtraConfig(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoConfigMap(a) assert.NoError(t, err) @@ -872,7 +970,13 @@ func TestReconcileArgoCD_reconcileArgoConfigMap_withExtraConfig(t *testing.T) { func Test_reconcileRBAC(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRBAC(a) assert.NoError(t, err) diff --git a/controllers/argocd/custommapper.go b/controllers/argocd/custommapper.go index f97e6db19..61715c073 100644 --- a/controllers/argocd/custommapper.go +++ b/controllers/argocd/custommapper.go @@ -14,7 +14,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -func (r *ReconcileArgoCD) clusterResourceMapper(o client.Object) []reconcile.Request { +func (r *ReconcileArgoCD) clusterResourceMapper(ctx context.Context, o client.Object) []reconcile.Request { crbAnnotations := o.GetAnnotations() namespacedArgoCDObject := client.ObjectKey{} @@ -65,7 +65,7 @@ func isOwnerOfInterest(owner v1.OwnerReference) bool { // tlsSecretMapper maps a watch event on a secret of type TLS back to the // ArgoCD object that we want to reconcile. -func (r *ReconcileArgoCD) tlsSecretMapper(o client.Object) []reconcile.Request { +func (r *ReconcileArgoCD) tlsSecretMapper(ctx context.Context, o client.Object) []reconcile.Request { var result = []reconcile.Request{} if !isSecretOfInterest(o) { @@ -127,7 +127,7 @@ func (r *ReconcileArgoCD) tlsSecretMapper(o client.Object) []reconcile.Request { // namespaceResourceMapper maps a watch event on a namespace, back to the // ArgoCD object that we want to reconcile. -func (r *ReconcileArgoCD) namespaceResourceMapper(o client.Object) []reconcile.Request { +func (r *ReconcileArgoCD) namespaceResourceMapper(ctx context.Context, o client.Object) []reconcile.Request { var result = []reconcile.Request{} labels := o.GetLabels() @@ -156,7 +156,7 @@ func (r *ReconcileArgoCD) namespaceResourceMapper(o client.Object) []reconcile.R // clusterSecretResourceMapper maps a watch event on a namespace, back to the // ArgoCD object that we want to reconcile. -func (r *ReconcileArgoCD) clusterSecretResourceMapper(o client.Object) []reconcile.Request { +func (r *ReconcileArgoCD) clusterSecretResourceMapper(ctx context.Context, o client.Object) []reconcile.Request { var result = []reconcile.Request{} labels := o.GetLabels() @@ -185,7 +185,7 @@ func (r *ReconcileArgoCD) clusterSecretResourceMapper(o client.Object) []reconci // applicationSetSCMTLSConfigMapMapper maps a watch event on a configmap with name "argocd-appset-gitlab-scm-tls-certs-cm", // back to the ArgoCD object that we want to reconcile. -func (r *ReconcileArgoCD) applicationSetSCMTLSConfigMapMapper(o client.Object) []reconcile.Request { +func (r *ReconcileArgoCD) applicationSetSCMTLSConfigMapMapper(ctx context.Context, o client.Object) []reconcile.Request { var result = []reconcile.Request{} if o.GetName() == common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName { diff --git a/controllers/argocd/custommapper_test.go b/controllers/argocd/custommapper_test.go index d33eeb455..acd32905e 100644 --- a/controllers/argocd/custommapper_test.go +++ b/controllers/argocd/custommapper_test.go @@ -5,6 +5,8 @@ import ( "reflect" "testing" + configv1 "github.com/openshift/api/config/v1" + routev1 "github.com/openshift/api/route/v1" "github.com/stretchr/testify/assert" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -96,7 +98,7 @@ func TestReconcileArgoCD_clusterRoleBindingMapper(t *testing.T) { Client: tt.fields.client, Scheme: tt.fields.scheme, } - if got := r.clusterResourceMapper(tt.args.o); !reflect.DeepEqual(got, tt.want) { + if got := r.clusterResourceMapper(context.TODO(), tt.args.o); !reflect.DeepEqual(got, tt.want) { t.Errorf("ReconcileArgoCD.clusterRoleBindingMapper() = %v, want %v", got, tt.want) } }) @@ -147,12 +149,14 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - argocd, - secret, - service, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret, service} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{ { NamespacedName: types.NamespacedName{ @@ -161,7 +165,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { }, }, } - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -202,13 +206,16 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - argocd, - secret, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{} - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -249,14 +256,16 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - argocd, - secret, - service, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret, service} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{} - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -277,10 +286,14 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - secret, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{ { NamespacedName: types.NamespacedName{ @@ -289,7 +302,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { }, }, } - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -307,12 +320,16 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - secret, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{} - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -364,12 +381,14 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - argocd, - secret, - service, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret, service} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{ { NamespacedName: types.NamespacedName{ @@ -378,7 +397,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { }, }, } - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -419,13 +438,16 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - argocd, - secret, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{} - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -466,14 +488,16 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - argocd, - secret, - service, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret, service} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{} - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -494,10 +518,14 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - secret, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{ { NamespacedName: types.NamespacedName{ @@ -506,7 +534,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { }, }, } - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -524,12 +552,16 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { corev1.TLSPrivateKeyKey: []byte("bar"), }, } - objs := []runtime.Object{ - secret, - } - r := makeReconciler(t, argocd, objs...) + + resObjs := []client.Object{argocd, secret} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + want := []reconcile.Request{} - got := r.tlsSecretMapper(secret) + got := r.tlsSecretMapper(context.TODO(), secret) if !reflect.DeepEqual(got, want) { t.Errorf("Reconciliation unsucessful: got: %v, want: %v", got, want) } @@ -539,7 +571,14 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { func TestReconcileArgoCD_namespaceResourceMapper(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + a.Namespace = "newTestNamespace" // Fake client returns an error if ResourceVersion is not nil @@ -586,7 +625,7 @@ func TestReconcileArgoCD_namespaceResourceMapper(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := r.namespaceResourceMapper(tt.o); !reflect.DeepEqual(got, tt.want) { + if got := r.namespaceResourceMapper(context.TODO(), tt.o); !reflect.DeepEqual(got, tt.want) { t.Errorf("ReconcileArgoCD.namespaceResourceMapper(), got = %v, want = %v", got, tt.want) } }) diff --git a/controllers/argocd/deployment_test.go b/controllers/argocd/deployment_test.go index 5c0ccecca..f96a187af 100644 --- a/controllers/argocd/deployment_test.go +++ b/controllers/argocd/deployment_test.go @@ -11,6 +11,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" resourcev1 "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" @@ -63,7 +64,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_replicas(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.Replicas = &test.replicas }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -126,7 +133,13 @@ func TestReconcileArgoCD_reconcile_ServerDeployment_replicas(t *testing.T) { a.Spec.Server.Replicas = test.initialReplicas a.Spec.Server.Autoscale.Enabled = test.autoscale }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileServerDeployment(a, false) assert.NoError(t, err) @@ -177,7 +190,12 @@ func TestReconcileArgoCD_reconcileRepoDeployment_loglevel(t *testing.T) { ll = lglv.Spec.Repo.LogLevel } - r := makeTestReconciler(t, lglv) + resObjs := []client.Object{lglv} + subresObjs := []client.Object{lglv} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(lglv, false) assert.NoError(t, err) @@ -211,7 +229,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_volumes(t *testing.T) { t.Run("create default volumes", func(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -236,7 +260,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_volumes(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.Volumes = []corev1.Volume{customVolume} }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -266,7 +296,13 @@ func TestReconcileArgoCD_reconcile_ServerDeployment_env(t *testing.T) { } timeout := 600 a.Spec.Repo.ExecTimeout = &timeout - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileServerDeployment(a, false) assert.NoError(t, err) @@ -300,7 +336,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_env(t *testing.T) { } timeout := 600 a.Spec.Repo.ExecTimeout = &timeout - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -322,7 +364,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_env(t *testing.T) { a := makeTestArgoCD() timeout := 600 a.Spec.Repo.ExecTimeout = &timeout - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -348,7 +396,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_env(t *testing.T) { Value: "20s", }, } - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -365,7 +419,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_env(t *testing.T) { t.Run("ExecTimeout not set", func(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -385,7 +445,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_mounts(t *testing.T) { t.Run("Create default mounts", func(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -409,7 +475,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_mounts(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo.VolumeMounts = []corev1.VolumeMount{testMount} }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -433,7 +505,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_initContainers(t *testing.T) { } a.Spec.Repo.InitContainers = []corev1.Container{ic} }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -469,7 +547,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_missingInitContainers(t *testin }, }, } - r := makeTestReconciler(t, a, d) + + resObjs := []client.Object{a, d} + subresObjs := []client.Object{a, d} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -510,7 +594,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_unexpectedInitContainer(t *test }, }, } - r := makeTestReconciler(t, a, d) + + resObjs := []client.Object{a, d} + subresObjs := []client.Object{a, d} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -527,7 +617,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_unexpectedInitContainer(t *test func TestReconcileArgoCD_reconcileRepoDeployment_command(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -563,7 +659,13 @@ func TestReconcileArgoCD_reconcileDeployments_proxy(t *testing.T) { }, } }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileDeployments(a, false) assert.NoError(t, err) @@ -592,7 +694,14 @@ func TestReconcileArgoCD_reconcileDeployments_proxy_update_existing(t *testing.T }, } }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := r.reconcileDeployments(a, false) assert.NoError(t, err) @@ -629,7 +738,13 @@ func TestReconcileArgoCD_reconcileDeployments_HA_proxy(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.HA.Enabled = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileDeployments(a, false) assert.NoError(t, err) @@ -646,7 +761,13 @@ func TestReconcileArgoCD_reconcileDeployments_HA_proxy_with_resources(t *testing a := makeTestArgoCDWithResources(func(a *argoproj.ArgoCD) { a.Spec.HA.Enabled = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) // test resource is Created on reconciliation assert.NoError(t, r.reconcileRedisHAProxyDeployment(a)) @@ -726,7 +847,13 @@ func TestReconcileArgoCD_reconcileRepoDeployment_updatesVolumeMounts(t *testing. }, }, } - r := makeTestReconciler(t, a, d) + + resObjs := []client.Object{a, d} + subresObjs := []client.Object{a, d} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoDeployment(a, false) assert.NoError(t, err) @@ -785,7 +912,14 @@ func TestReconcileArgoCD_reconcileDeployment_nodePlacement(t *testing.T) { Tolerations: deploymentDefaultTolerations(), } })) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := r.reconcileRepoDeployment(a, false) //can use other deployments as well assert.NoError(t, err) deployment := &appsv1.Deployment{} @@ -834,7 +968,14 @@ func TestReconcileArgocd_reconcileRepoServerRedisTLS(t *testing.T) { t.Run("with DisableTLSVerification = false (the default)", func(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, r.reconcileRepoDeployment(a, true)) deployment := &appsv1.Deployment{} @@ -863,7 +1004,14 @@ func TestReconcileArgocd_reconcileRepoServerRedisTLS(t *testing.T) { a := makeTestArgoCD(func(cd *argoproj.ArgoCD) { cd.Spec.Redis.DisableTLSVerification = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, r.reconcileRepoDeployment(a, true)) deployment := &appsv1.Deployment{} @@ -891,7 +1039,14 @@ func TestReconcileArgocd_reconcileRepoServerRedisTLS(t *testing.T) { func TestReconcileArgoCD_reconcileServerDeployment(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, r.reconcileServerDeployment(a, false)) deployment := &appsv1.Deployment{} @@ -998,7 +1153,13 @@ func TestReconcileArgoCD_reconcileServerDeployment(t *testing.T) { func TestArgoCDServerDeploymentCommand(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) baseCommand := []string{ "argocd-server", @@ -1104,7 +1265,13 @@ func TestReconcileArgoCD_reconcileServerDeploymentWithInsecure(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Insecure = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileServerDeployment(a, false)) @@ -1185,7 +1352,13 @@ func TestReconcileArgoCD_reconcileServerDeploymentWithInsecure(t *testing.T) { func TestReconcileArgoCD_reconcileServerDeploymentChangedToInsecure(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileServerDeployment(a, false)) @@ -1270,7 +1443,13 @@ func TestReconcileArgoCD_reconcileServerDeploymentChangedToInsecure(t *testing.T func TestReconcileArgoCD_reconcileRedisDeploymentWithoutTLS(t *testing.T) { cr := makeTestArgoCD() - r := makeTestReconciler(t, cr) + + resObjs := []client.Object{cr} + subresObjs := []client.Object{cr} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) want := []string{ "--save", @@ -1289,7 +1468,13 @@ func TestReconcileArgoCD_reconcileRedisDeploymentWithoutTLS(t *testing.T) { func TestReconcileArgoCD_reconcileRedisDeploymentWithTLS(t *testing.T) { cr := makeTestArgoCD() - r := makeTestReconciler(t, cr) + + resObjs := []client.Object{cr} + subresObjs := []client.Object{cr} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) want := []string{ "--save", "", @@ -1313,7 +1498,13 @@ func TestReconcileArgoCD_reconcileRedisDeploymentWithTLS(t *testing.T) { func TestReconcileArgoCD_reconcileRedisDeployment(t *testing.T) { // tests reconciler hook for redis deployment cr := makeTestArgoCD() - r := makeTestReconciler(t, cr) + + resObjs := []client.Object{cr} + subresObjs := []client.Object{cr} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) defer resetHooks()() Register(testDeploymentHook) @@ -1327,7 +1518,13 @@ func TestReconcileArgoCD_reconcileRedisDeployment(t *testing.T) { func TestReconcileArgoCD_reconcileRedisDeployment_testImageUpgrade(t *testing.T) { // tests reconciler hook for redis deployment cr := makeTestArgoCD() - r := makeTestReconciler(t, cr) + + resObjs := []client.Object{cr} + subresObjs := []client.Object{cr} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) defer resetHooks()() Register(testDeploymentHook) @@ -1349,7 +1546,13 @@ func TestReconcileArgoCD_reconcileRedisDeployment_testImageUpgrade(t *testing.T) func TestReconcileArgoCD_reconcileRedisDeployment_with_error(t *testing.T) { // tests reconciler hook for redis deployment cr := makeTestArgoCD() - r := makeTestReconciler(t, cr) + + resObjs := []client.Object{cr} + subresObjs := []client.Object{cr} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) defer resetHooks()() Register(testErrorHook) @@ -1675,7 +1878,14 @@ func TestReconcileArgoCD_reconcile_RepoServerChanges(t *testing.T) { a.Spec.Repo.MountSAToken = test.mountSAToken a.Spec.Repo.ServiceAccount = test.serviceAccount }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + sa := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: test.serviceAccount, @@ -1701,7 +1911,13 @@ func TestReconcileArgoCD_reconcile_RepoServerChanges(t *testing.T) { func TestArgoCDRepoServerDeploymentCommand(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) testRedisServerAddress := getRedisServerAddress(a) diff --git a/controllers/argocd/dex_test.go b/controllers/argocd/dex_test.go index 61e9f86a0..7c7acf74c 100644 --- a/controllers/argocd/dex_test.go +++ b/controllers/argocd/dex_test.go @@ -9,8 +9,10 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" resourcev1 "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -45,7 +47,14 @@ func TestReconcileArgoCD_reconcileDexDeployment_with_dex_disabled(t *testing.T) for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.setEnvFunc != nil { test.setEnvFunc(t, "true") } @@ -109,7 +118,14 @@ func TestReconcileArgoCD_reconcileDexDeployment_removes_dex_when_disabled(t *tes for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.setEnvFunc != nil { test.setEnvFunc(t, "false") } @@ -174,7 +190,14 @@ func TestReconcileArgoCD_reconcileDeployments_Dex_with_resources(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.setEnvFunc != nil { test.setEnvFunc(t, "false") } @@ -212,7 +235,14 @@ func TestReconcileArgoCD_reconcileDexDeployment(t *testing.T) { a.Spec.SSO = &argoproj.ArgoCDSSOSpec{ Provider: argoproj.SSOProviderTypeDex, } - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, r.reconcileDexDeployment(a)) deployment := &appsv1.Deployment{} @@ -435,7 +465,14 @@ func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.setEnvFunc != nil { test.setEnvFunc(t, "false") } @@ -513,7 +550,14 @@ func TestReconcileArgoCD_reconcileDexService_removes_dex_when_disabled(t *testin for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.setEnvFunc != nil { test.setEnvFunc(t, "false") } @@ -595,7 +639,14 @@ func TestReconcileArgoCD_reconcileDexServiceAccount_removes_dex_when_disabled(t for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.setEnvFunc != nil { test.setEnvFunc(t, "false") } @@ -678,7 +729,14 @@ func TestReconcileArgoCD_reconcileRole_dex_disabled(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, test.argoCD.Namespace, "")) rules := policyRuleForDexServer() @@ -766,7 +824,14 @@ func TestReconcileArgoCD_reconcileRoleBinding_dex_disabled(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, test.argoCD.Namespace, "")) rules := policyRuleForDexServer() diff --git a/controllers/argocd/grafana.go b/controllers/argocd/grafana.go index a6d12f08b..7568d5947 100644 --- a/controllers/argocd/grafana.go +++ b/controllers/argocd/grafana.go @@ -17,7 +17,6 @@ package argocd import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -114,7 +113,7 @@ func loadGrafanaConfigs() (map[string]string, error) { } for _, f := range configs { - config, err := ioutil.ReadFile(f) + config, err := os.ReadFile(f) if err != nil { return nil, err } @@ -132,7 +131,7 @@ func loadGrafanaTemplates(c *GrafanaConfig) (map[string]string, error) { data := make(map[string]string) templateDir := filepath.Join(getGrafanaConfigPath(), "templates") - entries, err := ioutil.ReadDir(templateDir) + entries, err := os.ReadDir(templateDir) if err != nil { return nil, err } diff --git a/controllers/argocd/hpa_test.go b/controllers/argocd/hpa_test.go index 1090bff80..b6c7dece7 100644 --- a/controllers/argocd/hpa_test.go +++ b/controllers/argocd/hpa_test.go @@ -4,10 +4,13 @@ import ( "context" "testing" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/stretchr/testify/assert" autoscaling "k8s.io/api/autoscaling/v1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -21,7 +24,13 @@ func TestReconcileHPA(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) existingHPA := newHorizontalPodAutoscalerWithSuffix("server", a) diff --git a/controllers/argocd/ingress_test.go b/controllers/argocd/ingress_test.go index 19f2bd8c8..4c84aa835 100644 --- a/controllers/argocd/ingress_test.go +++ b/controllers/argocd/ingress_test.go @@ -6,7 +6,9 @@ import ( "github.com/stretchr/testify/assert" networkingv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -39,7 +41,13 @@ func TestReconcileArgoCD_reconcile_ServerIngress_ingressClassName(t *testing.T) a.Spec.Server.Ingress.Enabled = true a.Spec.Server.Ingress.IngressClassName = test.ingressClassName }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoServerIngress(a) assert.NoError(t, err) @@ -81,7 +89,13 @@ func TestReconcileArgoCD_reconcile_ServerGRPCIngress_ingressClassName(t *testing a.Spec.Server.GRPC.Ingress.Enabled = true a.Spec.Server.GRPC.Ingress.IngressClassName = test.ingressClassName }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileArgoServerGRPCIngress(a) assert.NoError(t, err) @@ -124,7 +138,13 @@ func TestReconcileArgoCD_reconcile_GrafanaIngress_ingressClassName(t *testing.T) a.Spec.Grafana.Ingress.Enabled = true a.Spec.Grafana.Ingress.IngressClassName = test.ingressClassName }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileGrafanaIngress(a) assert.NoError(t, err) @@ -167,7 +187,13 @@ func TestReconcileArgoCD_reconcile_PrometheusIngress_ingressClassName(t *testing a.Spec.Prometheus.Ingress.Enabled = true a.Spec.Prometheus.Ingress.IngressClassName = test.ingressClassName }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcilePrometheusIngress(a) assert.NoError(t, err) @@ -194,7 +220,14 @@ func TestReconcileApplicationSetService_Ingress(t *testing.T) { }, } a.Spec.ApplicationSet = &obj - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + ingress := newIngressWithSuffix(common.ApplicationSetServiceNameSuffix, a) assert.NoError(t, r.reconcileApplicationSetControllerIngress(a)) assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Namespace: ingress.Namespace, Name: ingress.Name}, ingress)) diff --git a/controllers/argocd/keycloak.go b/controllers/argocd/keycloak.go index f4a025488..be368e2df 100644 --- a/controllers/argocd/keycloak.go +++ b/controllers/argocd/keycloak.go @@ -26,7 +26,6 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" - keycloakv1alpha1 "github.com/keycloak/keycloak-operator/pkg/apis/keycloak/v1alpha1" appsv1 "github.com/openshift/api/apps/v1" oappsv1 "github.com/openshift/api/apps/v1" oauthv1 "github.com/openshift/api/oauth/v1" @@ -89,70 +88,6 @@ var ( controllerRef bool = true ) -// KeycloakPostData defines the values required to update Keycloak Realm. -type keycloakConfig struct { - ArgoName string - ArgoNamespace string - Username string - Password string - KeycloakURL string - ArgoCDURL string - KeycloakServerCert []byte - VerifyTLS bool -} - -type oidcConfig struct { - Name string `json:"name"` - Issuer string `json:"issuer"` - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - RequestedScope []string `json:"requestedScopes"` - RootCA string `json:"rootCA,omitempty"` -} - -// KeycloakIdentityProviderMapper defines IdentityProvider Mappers -// issue: https://github.com/keycloak/keycloak-operator/issues/471 -type KeycloakIdentityProviderMapper struct { - // Name - // +optional - Name string `json:"name,omitempty"` - // Identity Provider Alias. - // +optional - IdentityProviderAlias string `json:"identityProviderAlias,omitempty"` - // Identity Provider Mapper. - // +optional - IdentityProviderMapper string `json:"identityProviderMapper,omitempty"` - // Identity Provider Mapper config. - // +optional - Config map[string]string `json:"config,omitempty"` -} - -// CustomKeycloakAPIRealm is an extention type of KeycloakAPIRealm as is it does not -// support IdentityProvider Mappers -// issue: https://github.com/keycloak/keycloak-operator/issues/471 -type CustomKeycloakAPIRealm struct { - // Realm name. - Realm string `json:"realm"` - // Realm enabled flag. - // +optional - Enabled bool `json:"enabled"` - // Require SSL - // +optional - SslRequired string `json:"sslRequired,omitempty"` - // A set of Keycloak Clients. - // +optional - Clients []*keycloakv1alpha1.KeycloakAPIClient `json:"clients,omitempty"` - // Client scopes - // +optional - ClientScopes []keycloakv1alpha1.KeycloakClientScope `json:"clientScopes,omitempty"` - // A set of Identity Providers. - // +optional - IdentityProviders []*keycloakv1alpha1.KeycloakIdentityProvider `json:"identityProviders,omitempty"` - // KeycloakIdentityProviderMapper defines IdentityProvider Mappers - // issue: https://github.com/keycloak/keycloak-operator/issues/471 - IdentityProviderMappers []*KeycloakIdentityProviderMapper `json:"identityProviderMappers,omitempty"` -} - // getKeycloakContainerImage will return the container image for the Keycloak. // // There are three possible options for configuring the image, and this is the @@ -900,7 +835,7 @@ func createRealmConfig(cfg *keycloakConfig) ([]byte, error) { Realm: keycloakRealm, Enabled: true, SslRequired: "external", - Clients: []*keycloakv1alpha1.KeycloakAPIClient{ + Clients: []*KeycloakAPIClient{ { ClientID: keycloakClient, Name: keycloakClient, @@ -922,11 +857,11 @@ func createRealmConfig(cfg *keycloakConfig) ([]byte, error) { StandardFlowEnabled: true, }, }, - ClientScopes: []keycloakv1alpha1.KeycloakClientScope{ + ClientScopes: []KeycloakClientScope{ { Name: "groups", Protocol: "openid-connect", - ProtocolMappers: []keycloakv1alpha1.KeycloakProtocolMapper{ + ProtocolMappers: []KeycloakProtocolMapper{ { Name: "groups", Protocol: "openid-connect", @@ -946,7 +881,7 @@ func createRealmConfig(cfg *keycloakConfig) ([]byte, error) { { Name: "email", Protocol: "openid-connect", - ProtocolMappers: []keycloakv1alpha1.KeycloakProtocolMapper{ + ProtocolMappers: []KeycloakProtocolMapper{ { Name: "email", Protocol: "openid-connect", @@ -981,7 +916,7 @@ func createRealmConfig(cfg *keycloakConfig) ([]byte, error) { baseURL = getOpenShiftAPIURL() } - ks.IdentityProviders = []*keycloakv1alpha1.KeycloakIdentityProvider{ + ks.IdentityProviders = []*KeycloakIdentityProvider{ { Alias: "openshift-v4", DisplayName: "Login with OpenShift", diff --git a/controllers/argocd/keycloak_client.go b/controllers/argocd/keycloak_client.go index 6078e88b4..f7f2782c3 100644 --- a/controllers/argocd/keycloak_client.go +++ b/controllers/argocd/keycloak_client.go @@ -6,12 +6,11 @@ import ( "crypto/x509" json "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "strings" - keycloakv1alpha1 "github.com/keycloak/keycloak-operator/pkg/apis/keycloak/v1alpha1" "github.com/pkg/errors" ) @@ -87,12 +86,12 @@ func (h *httpclient) login(user, pass string) error { } defer res.Body.Close() - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return err } - tokenRes := &keycloakv1alpha1.TokenResponse{} + tokenRes := &TokenResponse{} err = json.Unmarshal(body, tokenRes) if err != nil { return err diff --git a/controllers/argocd/keycloak_client_test.go b/controllers/argocd/keycloak_client_test.go index fafc0f212..cd988f6a5 100644 --- a/controllers/argocd/keycloak_client_test.go +++ b/controllers/argocd/keycloak_client_test.go @@ -8,7 +8,6 @@ import ( "encoding/pem" jsoniter "github.com/json-iterator/go" - keycloakv1alpha1 "github.com/keycloak/keycloak-operator/pkg/apis/keycloak/v1alpha1" "github.com/stretchr/testify/assert" ) @@ -38,7 +37,7 @@ func TestKeycloak_testLogin(t *testing.T) { assert.Equal(t, authURL, req.URL.Path) assert.Equal(t, req.Method, http.MethodPost) - response := keycloakv1alpha1.TokenResponse{ + response := TokenResponse{ AccessToken: "dummy", } diff --git a/controllers/argocd/keycloak_test.go b/controllers/argocd/keycloak_test.go index c6d65fdda..58670e341 100644 --- a/controllers/argocd/keycloak_test.go +++ b/controllers/argocd/keycloak_test.go @@ -20,11 +20,15 @@ import ( "testing" appsv1 "github.com/openshift/api/apps/v1" + oappsv1 "github.com/openshift/api/apps/v1" routev1 "github.com/openshift/api/route/v1" + templatev1 "github.com/openshift/api/template/v1" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" resourcev1 "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" @@ -346,7 +350,13 @@ func TestKeycloak_testRealmConfigCreation(t *testing.T) { func TestKeycloak_testServerCert(t *testing.T) { a := makeTestArgoCDForKeycloak() - r := makeFakeReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sslCertsSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -413,7 +423,12 @@ func TestKeycloakConfigVerifyTLSForOpenShift(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeFakeReconciler(t, test.argoCD) + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) keycloakRoute := &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ diff --git a/controllers/argocd/keycloak_types.go b/controllers/argocd/keycloak_types.go new file mode 100644 index 000000000..c1460691e --- /dev/null +++ b/controllers/argocd/keycloak_types.go @@ -0,0 +1,159 @@ +package argocd + +type KeycloakAPIClient struct { + // Client ID. + // +kubebuilder:validation:Required + ClientID string `json:"clientId"` + // Client name. + // +optional + Name string `json:"name,omitempty"` + // What Client authentication type to use. + // +optional + ClientAuthenticatorType string `json:"clientAuthenticatorType,omitempty"` + // Client Secret. The Operator will automatically create a Secret based on this value. + // +optional + Secret string `json:"secret,omitempty"` + // Application base URL. + // +optional + BaseURL string `json:"baseUrl,omitempty"` + // Application Admin URL. + // +optional + AdminURL string `json:"adminUrl,omitempty"` + // Application root URL. + // +optional + RootURL string `json:"rootUrl,omitempty"` + // A list of valid Redirection URLs. + // +optional + RedirectUris []string `json:"redirectUris,omitempty"` + // A list of valid Web Origins. + // +optional + WebOrigins []string `json:"webOrigins,omitempty"` + // True if Standard flow is enabled. + // +optional + StandardFlowEnabled bool `json:"standardFlowEnabled"` + // A list of default client scopes. Default client scopes are + // always applied when issuing OpenID Connect tokens or SAML + // assertions for this client. + // +optional + DefaultClientScopes []string `json:"defaultClientScopes,omitempty"` +} + +type KeycloakClientScope struct { + // +optional + Attributes map[string]string `json:"attributes,omitempty"` + // +optional + ID string `json:"id,omitempty"` + // +optional + Name string `json:"name,omitempty"` + // +optional + Protocol string `json:"protocol,omitempty"` + // Protocol Mappers. + // +optional + ProtocolMappers []KeycloakProtocolMapper `json:"protocolMappers,omitempty"` +} + +type KeycloakProtocolMapper struct { + // Protocol Mapper ID. + // +optional + ID string `json:"id,omitempty"` + // Protocol Mapper Name. + // +optional + Name string `json:"name,omitempty"` + // Protocol to use. + // +optional + Protocol string `json:"protocol,omitempty"` + // Protocol Mapper to use + // +optional + ProtocolMapper string `json:"protocolMapper,omitempty"` + // Config options. + // +optional + Config map[string]string `json:"config,omitempty"` +} + +type KeycloakIdentityProvider struct { + // Identity Provider Alias. + // +optional + Alias string `json:"alias,omitempty"` + // Identity Provider Display Name. + // +optional + DisplayName string `json:"displayName,omitempty"` + // Identity Provider ID. + // +optional + ProviderID string `json:"providerId,omitempty"` + // Identity Provider config. + // +optional + Config map[string]string `json:"config,omitempty"` +} + +type TokenResponse struct { + // Token Response Access Token. + // +optional + AccessToken string `json:"access_token"` + // Token Response Error. + // +optional + Error string `json:"error"` +} + +// KeycloakPostData defines the values required to update Keycloak Realm. +type keycloakConfig struct { + ArgoName string + ArgoNamespace string + Username string + Password string + KeycloakURL string + ArgoCDURL string + KeycloakServerCert []byte + VerifyTLS bool +} + +type oidcConfig struct { + Name string `json:"name"` + Issuer string `json:"issuer"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + RequestedScope []string `json:"requestedScopes"` + RootCA string `json:"rootCA,omitempty"` +} + +// KeycloakIdentityProviderMapper defines IdentityProvider Mappers +// issue: https://github.com/keycloak/keycloak-operator/issues/471 +type KeycloakIdentityProviderMapper struct { + // Name + // +optional + Name string `json:"name,omitempty"` + // Identity Provider Alias. + // +optional + IdentityProviderAlias string `json:"identityProviderAlias,omitempty"` + // Identity Provider Mapper. + // +optional + IdentityProviderMapper string `json:"identityProviderMapper,omitempty"` + // Identity Provider Mapper config. + // +optional + Config map[string]string `json:"config,omitempty"` +} + +// CustomKeycloakAPIRealm is an extention type of KeycloakAPIRealm as is it does not +// support IdentityProvider Mappers +// issue: https://github.com/keycloak/keycloak-operator/issues/471 +type CustomKeycloakAPIRealm struct { + // Realm name. + Realm string `json:"realm"` + // Realm enabled flag. + // +optional + Enabled bool `json:"enabled"` + // Require SSL + // +optional + SslRequired string `json:"sslRequired,omitempty"` + // A set of Keycloak Clients. + // +optional + Clients []*KeycloakAPIClient `json:"clients,omitempty"` + // Client scopes + // +optional + ClientScopes []KeycloakClientScope `json:"clientScopes,omitempty"` + // A set of Identity Providers. + // +optional + IdentityProviders []*KeycloakIdentityProvider `json:"identityProviders,omitempty"` + // KeycloakIdentityProviderMapper defines IdentityProvider Mappers + // issue: https://github.com/keycloak/keycloak-operator/issues/471 + IdentityProviderMappers []*KeycloakIdentityProviderMapper `json:"identityProviderMappers,omitempty"` +} diff --git a/controllers/argocd/notifications_test.go b/controllers/argocd/notifications_test.go index 3b4951e02..11bbd5f18 100644 --- a/controllers/argocd/notifications_test.go +++ b/controllers/argocd/notifications_test.go @@ -11,8 +11,10 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -26,7 +28,12 @@ func TestReconcileNotifications_CreateRoles(t *testing.T) { a.Spec.Notifications.Enabled = true }) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) _, err := r.reconcileNotificationsRole(a) assert.NoError(t, err) @@ -58,7 +65,12 @@ func TestReconcileNotifications_CreateServiceAccount(t *testing.T) { a.Spec.Notifications.Enabled = true }) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) desiredSa, err := r.reconcileNotificationsServiceAccount(a) assert.NoError(t, err) @@ -88,7 +100,13 @@ func TestReconcileNotifications_CreateRoleBinding(t *testing.T) { a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Notifications.Enabled = true }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) role := &rbacv1.Role{ObjectMeta: metav1.ObjectMeta{Name: "role-name"}} sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "sa-name"}} @@ -125,8 +143,12 @@ func TestReconcileNotifications_CreateDeployments(t *testing.T) { a.Spec.Notifications.Enabled = true }) - r := makeTestReconciler(t, a) - + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) @@ -236,7 +258,12 @@ func TestReconcileNotifications_CreateSecret(t *testing.T) { a.Spec.Notifications.Enabled = true }) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileNotificationsSecret(a) assert.NoError(t, err) @@ -261,7 +288,12 @@ func TestReconcileNotifications_CreateConfigMap(t *testing.T) { a.Spec.Notifications.Enabled = true }) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileNotificationsConfigMap(a) assert.NoError(t, err) @@ -295,7 +327,12 @@ func TestReconcileNotifications_testEnvVars(t *testing.T) { a.Spec.Notifications.Env = envMap }) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) @@ -353,7 +390,12 @@ func TestReconcileNotifications_testLogLevel(t *testing.T) { a.Spec.Notifications.LogLevel = testLogLevel }) - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) sa := corev1.ServiceAccount{} assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) diff --git a/controllers/argocd/prometheus_test.go b/controllers/argocd/prometheus_test.go index 0cebeb7b8..6bcab8b04 100644 --- a/controllers/argocd/prometheus_test.go +++ b/controllers/argocd/prometheus_test.go @@ -8,8 +8,10 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/client" ) func TestReconcileWorkloadStatusAlertRule(t *testing.T) { @@ -162,7 +164,13 @@ func TestReconcileWorkloadStatusAlertRule(t *testing.T) { }, } - r := makeTestReconciler(t, test.argocd) + resObjs := []client.Object{test.argocd} + subresObjs := []client.Object{test.argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := monitoringv1.AddToScheme(r.Scheme) assert.NoError(t, err) diff --git a/controllers/argocd/role.go b/controllers/argocd/role.go index 923cfe159..9118d83ac 100644 --- a/controllers/argocd/role.go +++ b/controllers/argocd/role.go @@ -187,7 +187,6 @@ func (r *ReconcileArgoCD) reconcileRole(name string, policyRules []v1.PolicyRule } func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name string, policyRules []v1.PolicyRule, cr *argoproj.ArgoCD) error { - var roles []*v1.Role // create policy rules for each source namespace for ArgoCD Server for _, sourceNamespace := range cr.Spec.SourceNamespaces { @@ -262,7 +261,6 @@ func (r *ReconcileArgoCD) reconcileRoleForApplicationSourceNamespaces(name strin return err } } - roles = append(roles, &existingRole) if _, ok := r.ManagedSourceNamespaces[sourceNamespace]; !ok { r.ManagedSourceNamespaces[sourceNamespace] = "" diff --git a/controllers/argocd/role_test.go b/controllers/argocd/role_test.go index db5bc53d9..c112094e7 100644 --- a/controllers/argocd/role_test.go +++ b/controllers/argocd/role_test.go @@ -11,7 +11,9 @@ import ( v1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -21,7 +23,14 @@ import ( func TestReconcileArgoCD_reconcileRole(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "newNamespaceTest", a.Namespace)) @@ -53,7 +62,14 @@ func TestReconcileArgoCD_reconcileRole(t *testing.T) { func TestReconcileArgoCD_reconcileRole_for_new_namespace(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "newNamespaceTest", a.Namespace)) @@ -93,7 +109,13 @@ func TestReconcileArgoCD_reconcileRole_for_new_namespace(t *testing.T) { func TestReconcileArgoCD_reconcileClusterRole(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) workloadIdentifier := common.ArgoCDApplicationControllerComponent clusterRoleName := GenerateUniqueResourceName(workloadIdentifier, a) @@ -145,7 +167,14 @@ func TestReconcileArgoCD_reconcileRoleForApplicationSourceNamespaces(t *testing. sourceNamespace, }, } - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespaceManagedByClusterArgoCDLabel(r, sourceNamespace, a.Namespace)) @@ -166,7 +195,14 @@ func TestReconcileArgoCD_reconcileRoleForApplicationSourceNamespaces(t *testing. func TestReconcileArgoCD_RoleHooks(t *testing.T) { defer resetHooks()() a := makeTestArgoCD() - r := makeTestReconciler(t) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) Register(testRoleHook) @@ -184,7 +220,14 @@ func TestReconcileArgoCD_RoleHooks(t *testing.T) { func TestReconcileArgoCD_reconcileRole_custom_role(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "namespace-custom-role", a.Namespace)) @@ -225,7 +268,14 @@ func TestReconcileArgoCD_reconcileRole_custom_role(t *testing.T) { func TestReconcileRoles_ManagedTerminatingNamespace(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) // Create a managed namespace diff --git a/controllers/argocd/rolebinding.go b/controllers/argocd/rolebinding.go index 37a45b22f..efa6c852d 100644 --- a/controllers/argocd/rolebinding.go +++ b/controllers/argocd/rolebinding.go @@ -58,7 +58,7 @@ func newRoleBinding(cr *argoproj.ArgoCD) *v1.RoleBinding { func newRoleBindingForSupportNamespaces(cr *argoproj.ArgoCD, namespace string) *v1.RoleBinding { return &v1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: getRoleBindingNameForSourceNamespaces(cr.Name, cr.Namespace, namespace), + Name: getRoleBindingNameForSourceNamespaces(cr.Name, namespace), Labels: argoutil.LabelsForCluster(cr), Annotations: argoutil.AnnotationsForCluster(cr), Namespace: namespace, @@ -66,7 +66,7 @@ func newRoleBindingForSupportNamespaces(cr *argoproj.ArgoCD, namespace string) * } } -func getRoleBindingNameForSourceNamespaces(argocdName, argocdNamespace, targetNamespace string) string { +func getRoleBindingNameForSourceNamespaces(argocdName, targetNamespace string) string { return fmt.Sprintf("%s_%s", argocdName, targetNamespace) } diff --git a/controllers/argocd/rolebinding_test.go b/controllers/argocd/rolebinding_test.go index ac25e1274..62f0993a0 100644 --- a/controllers/argocd/rolebinding_test.go +++ b/controllers/argocd/rolebinding_test.go @@ -9,7 +9,9 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -19,7 +21,14 @@ import ( func TestReconcileArgoCD_reconcileRoleBinding(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + p := policyRuleForApplicationController() assert.NoError(t, createNamespace(r, a.Namespace, "")) @@ -49,7 +58,13 @@ func TestReconcileArgoCD_reconcileRoleBinding(t *testing.T) { func TestReconcileArgoCD_reconcileRoleBinding_for_new_namespace(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "newTestNamespace", a.Namespace)) @@ -85,7 +100,13 @@ func TestReconcileArgoCD_reconcileRoleBinding_for_new_namespace(t *testing.T) { // or remains terminating may be because of some resources in the namespace not getting deleted. func TestReconcileRoleBinding_for_Managed_Teminating_Namespace(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, createNamespace(r, "managedNS", a.Namespace)) @@ -140,7 +161,13 @@ func TestReconcileRoleBinding_for_Managed_Teminating_Namespace(t *testing.T) { func TestReconcileArgoCD_reconcileClusterRoleBinding(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) workloadIdentifier := "x" expectedClusterRole := &rbacv1.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: workloadIdentifier}} @@ -166,7 +193,14 @@ func TestReconcileArgoCD_reconcileClusterRoleBinding(t *testing.T) { func TestReconcileArgoCD_reconcileRoleBinding_custom_role(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + p := policyRuleForApplicationController() assert.NoError(t, createNamespace(r, a.Namespace, "")) @@ -220,7 +254,14 @@ func TestReconcileArgoCD_reconcileRoleBinding_forSourceNamespaces(t *testing.T) sourceNamespace, }, } - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + p := policyRuleForApplicationController() assert.NoError(t, createNamespace(r, a.Namespace, "")) @@ -231,7 +272,7 @@ func TestReconcileArgoCD_reconcileRoleBinding_forSourceNamespaces(t *testing.T) assert.NoError(t, r.reconcileRoleBinding(workloadIdentifier, p, a)) roleBinding := &rbacv1.RoleBinding{} - expectedName := getRoleBindingNameForSourceNamespaces(a.Name, a.Namespace, sourceNamespace) + expectedName := getRoleBindingNameForSourceNamespaces(a.Name, sourceNamespace) assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{Name: expectedName, Namespace: sourceNamespace}, roleBinding)) diff --git a/controllers/argocd/route_test.go b/controllers/argocd/route_test.go index 4e3bd3fca..4b2c6dfb0 100644 --- a/controllers/argocd/route_test.go +++ b/controllers/argocd/route_test.go @@ -33,10 +33,14 @@ func TestReconcileRouteSetLabels(t *testing.T) { labels["my-key"] = "my-value" a.Spec.Server.Route.Labels = labels }) - objs := []runtime.Object{ - argoCD, - } - r := makeReconciler(t, argoCD, objs...) + + resObjs := []client.Object{argoCD} + subresObjs := []client.Object{argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, argoCD.Namespace, "")) req := reconcile.Request{ @@ -65,10 +69,14 @@ func TestReconcileRouteSetsInsecure(t *testing.T) { argoCD := makeArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Server.Route.Enabled = true }) - objs := []runtime.Object{ - argoCD, - } - r := makeReconciler(t, argoCD, objs...) + + resObjs := []client.Object{argoCD} + subresObjs := []client.Object{argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, argoCD.Namespace, "")) req := reconcile.Request{ @@ -137,10 +145,14 @@ func TestReconcileRouteUnsetsInsecure(t *testing.T) { a.Spec.Server.Route.Enabled = true a.Spec.Server.Insecure = true }) - objs := []runtime.Object{ - argoCD, - } - r := makeReconciler(t, argoCD, objs...) + + resObjs := []client.Object{argoCD} + subresObjs := []client.Object{argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, argoCD.Namespace, "")) req := reconcile.Request{ @@ -207,7 +219,15 @@ func makeReconciler(t *testing.T, acd *argoproj.ArgoCD, objs ...runtime.Object) s.AddKnownTypes(argoproj.GroupVersion, acd) routev1.Install(s) configv1.Install(s) - cl := fake.NewFakeClient(objs...) + + clientObjs := []client.Object{} + for _, obj := range objs { + clientObj := obj.(client.Object) + clientObjs = append(clientObjs, clientObj) + } + + cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).WithStatusSubresource(clientObjs...).Build() + return &ReconcileArgoCD{ Client: cl, Scheme: s, diff --git a/controllers/argocd/secret_test.go b/controllers/argocd/secret_test.go index b3d7b470f..f694f43ef 100644 --- a/controllers/argocd/secret_test.go +++ b/controllers/argocd/secret_test.go @@ -8,6 +8,8 @@ import ( "sort" "testing" + configv1 "github.com/openshift/api/config/v1" + routev1 "github.com/openshift/api/route/v1" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -15,6 +17,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -105,16 +108,21 @@ func Test_ReconcileArgoCD_ReconcileRepoTLSSecret(t *testing.T) { serverDepl := newDeploymentWithSuffix("server", "server", argocd) repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", argocd) ctrlSts := newStatefulSetWithSuffix("application-controller", "application-controller", argocd) - objs := []runtime.Object{ - argocd, + + resObjs := []client.Object{argocd, secret, service, serverDepl, repoDepl, - ctrlSts, - } - - r := makeReconciler(t, argocd, objs...) + ctrlSts} + subresObjs := []client.Object{argocd, + serverDepl, + repoDepl, + ctrlSts} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRepoServerTLSSecret(argocd) if err != nil { @@ -218,7 +226,14 @@ func Test_ReconcileArgoCD_ReconcileExistingArgoSecret(t *testing.T) { clusterSecret := argoutil.NewSecretWithSuffix(argocd, "cluster") clusterSecret.Data = map[string][]byte{common.ArgoCDKeyAdminPassword: []byte("something")} tlsSecret := argoutil.NewSecretWithSuffix(argocd, "tls") - r := makeTestReconciler(t, argocd) + + resObjs := []client.Object{argocd} + subresObjs := []client.Object{argocd} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + r.Client.Create(context.TODO(), clusterSecret) r.Client.Create(context.TODO(), tlsSecret) @@ -300,17 +315,23 @@ func Test_ReconcileArgoCD_ReconcileRedisTLSSecret(t *testing.T) { repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", argocd) redisDepl := newDeploymentWithSuffix("redis", "redis", argocd) ctrlSts := newStatefulSetWithSuffix("application-controller", "application-controller", argocd) - objs := []runtime.Object{ - argocd, + + resObjs := []client.Object{argocd, secret, service, serverDepl, repoDepl, - redisDepl, ctrlSts, - } - - r := makeReconciler(t, argocd, objs...) + redisDepl} + subresObjs := []client.Object{argocd, + serverDepl, + repoDepl, + ctrlSts, + redisDepl} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.reconcileRedisTLSSecret(argocd, true) if err != nil { @@ -421,7 +442,14 @@ func Test_ReconcileArgoCD_ReconcileRedisTLSSecret(t *testing.T) { func Test_ReconcileArgoCD_ClusterPermissionsSecret(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) testSecret := argoutil.NewSecretWithSuffix(a, "default-cluster-config") diff --git a/controllers/argocd/service_account_test.go b/controllers/argocd/service_account_test.go index 3ab33951c..01ef428dd 100644 --- a/controllers/argocd/service_account_test.go +++ b/controllers/argocd/service_account_test.go @@ -20,17 +20,27 @@ import ( "os" "testing" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" ) func TestReconcileArgoCD_reconcileServiceAccountPermissions(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) // objective is to verify if the right rule associations have happened. @@ -70,7 +80,13 @@ func TestReconcileArgoCD_reconcileServiceAccountPermissions(t *testing.T) { func TestReconcileArgoCD_reconcileServiceAccountClusterPermissions(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) workloadIdentifier := "xrb" expectedClusterRoleBindingName := fmt.Sprintf("%s-%s-%s", a.Name, a.Namespace, workloadIdentifier) diff --git a/controllers/argocd/sso_test.go b/controllers/argocd/sso_test.go index 4c8f8522a..099a973e0 100644 --- a/controllers/argocd/sso_test.go +++ b/controllers/argocd/sso_test.go @@ -29,37 +29,25 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) -func makeFakeReconciler(t *testing.T, acd *argoproj.ArgoCD, objs ...runtime.Object) *ReconcileArgoCD { - t.Helper() - s := scheme.Scheme - // Register template scheme - s.AddKnownTypes(templatev1.SchemeGroupVersion, objs...) - s.AddKnownTypes(oappsv1.SchemeGroupVersion, objs...) - assert.NoError(t, argoproj.AddToScheme(s)) - templatev1.Install(s) - oappsv1.Install(s) - routev1.Install(s) - - cl := fake.NewFakeClientWithScheme(s, objs...) - return &ReconcileArgoCD{ - Client: cl, - Scheme: s, - } -} - func TestReconcile_testKeycloakTemplateInstance(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCDForKeycloak() templateAPIFound = true - r := makeFakeReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, r.reconcileSSO(a)) @@ -77,7 +65,14 @@ func TestReconcile_testKeycloakTemplateInstance(t *testing.T) { func TestReconcile_noTemplateInstance(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCDForKeycloak() - r := makeFakeReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, r.reconcileSSO(a)) @@ -216,7 +211,14 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, test.argoCD.Namespace, "")) err := r.reconcileSSO(test.argoCD) @@ -248,7 +250,14 @@ func TestReconcile_testKeycloakK8sInstance(t *testing.T) { // Cluster does not have a template instance templateAPIFound = false - r := makeReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, r.reconcileSSO(a)) @@ -260,7 +269,14 @@ func TestReconcile_testKeycloakInstanceResources(t *testing.T) { // Cluster does not have a template instance templateAPIFound = false - r := makeReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, r.reconcileSSO(a)) diff --git a/controllers/argocd/statefulset_test.go b/controllers/argocd/statefulset_test.go index 4157cbcfe..c5c779a86 100644 --- a/controllers/argocd/statefulset_test.go +++ b/controllers/argocd/statefulset_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -73,7 +74,14 @@ func TestReconcileArgoCD_reconcileRedisStatefulSet_HA_disabled(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + s := newStatefulSetWithSuffix("redis-ha-server", "redis", a) assert.NoError(t, r.reconcileRedisStatefulSet(a)) @@ -85,7 +93,14 @@ func TestReconcileArgoCD_reconcileRedisStatefulSet_HA_enabled(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + s := newStatefulSetWithSuffix("redis-ha-server", "redis", a) a.Spec.HA.Enabled = true @@ -124,7 +139,13 @@ func TestReconcileArgoCD_reconcileRedisStatefulSet_HA_enabled(t *testing.T) { func TestReconcileArgoCD_reconcileApplicationController(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileApplicationControllerStatefulSet(a, false)) @@ -162,7 +183,13 @@ func TestReconcileArgoCD_reconcileApplicationController(t *testing.T) { func TestReconcileArgoCD_reconcileApplicationController_withRedisTLS(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileApplicationControllerStatefulSet(a, true)) @@ -194,7 +221,13 @@ func TestReconcileArgoCD_reconcileApplicationController_withRedisTLS(t *testing. func TestReconcileArgoCD_reconcileApplicationController_withUpdate(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileApplicationControllerStatefulSet(a, false)) @@ -227,7 +260,13 @@ func TestReconcileArgoCD_reconcileApplicationController_withUpdate(t *testing.T) func TestReconcileArgoCD_reconcileApplicationController_withUpgrade(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) deploy := newDeploymentWithSuffix("application-controller", "application-controller", a) assert.NoError(t, r.Client.Create(context.TODO(), deploy)) @@ -253,7 +292,13 @@ func TestReconcileArgoCD_reconcileApplicationController_withResources(t *testing Storage: &argoprojv1alpha1.ArgoCDExportStorageSpec{}, }, } - r := makeTestReconciler(t, a, &ex) + + resObjs := []client.Object{a, &ex} + subresObjs := []client.Object{a, &ex} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, argoprojv1alpha1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileApplicationControllerStatefulSet(a, false)) @@ -345,7 +390,13 @@ func TestReconcileArgoCD_reconcileApplicationController_withSharding(t *testing. a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Controller.Sharding = st.sharding }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileApplicationControllerStatefulSet(a, false)) @@ -384,7 +435,13 @@ func TestReconcileArgoCD_reconcileApplicationController_withAppSync(t *testing.T a := makeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Controller.AppSync = &metav1.Duration{Duration: time.Minute * 10} }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileApplicationControllerStatefulSet(a, false)) @@ -475,11 +532,16 @@ func Test_ContainsValidImage(t *testing.T) { }, }, } - objs := []runtime.Object{ + objs := []client.Object{ po, a, } - r := makeTestReconciler(t, objs...) + + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, objs, objs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if containsInvalidImage(a, r) { t.Fatalf("containsInvalidImage failed, got true, expected false") } @@ -545,7 +607,13 @@ func TestReconcileArgoCD_reconcileApplicationController_withDynamicSharding(t *t clusterSecret3 := argoutil.NewSecretWithSuffix(a, "cluster3") clusterSecret3.Labels = map[string]string{common.ArgoCDSecretTypeLabel: "cluster"} - r := makeTestReconciler(t, a) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, r.Client.Create(context.TODO(), clusterSecret1)) assert.NoError(t, r.Client.Create(context.TODO(), clusterSecret2)) assert.NoError(t, r.Client.Create(context.TODO(), clusterSecret3)) diff --git a/controllers/argocd/status_test.go b/controllers/argocd/status_test.go index b045b94c0..241120785 100644 --- a/controllers/argocd/status_test.go +++ b/controllers/argocd/status_test.go @@ -7,12 +7,13 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" oappsv1 "github.com/openshift/api/apps/v1" + configv1 "github.com/openshift/api/config/v1" routev1 "github.com/openshift/api/route/v1" "github.com/stretchr/testify/assert" - v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" ) @@ -20,7 +21,14 @@ func TestReconcileArgoCD_reconcileStatusKeycloak_K8s(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCDForKeycloak() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) d := newKeycloakDeployment(a) @@ -47,7 +55,14 @@ func TestReconcileArgoCD_reconcileStatusKeycloak_OpenShift(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCDForKeycloak() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) assert.NoError(t, oappsv1.AddToScheme(r.Scheme)) @@ -61,15 +76,19 @@ func TestReconcileArgoCD_reconcileStatusKeycloak_OpenShift(t *testing.T) { _ = r.reconcileStatusKeycloak(a) assert.Equal(t, "Unknown", a.Status.SSO) + // create new client with dc object already present, but with 0 ready replicas to simulate // keycloak installation started - r.Client.Create(context.TODO(), dc) + resObjs = append(resObjs, dc) + subresObjs = append(subresObjs, dc) + r.Client = makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) _ = r.reconcileStatusKeycloak(a) assert.Equal(t, "Pending", a.Status.SSO) + // create new client with dc object already present, with 1 ready replica to simulate // keycloak installation completed dc.Status.ReadyReplicas = dc.Spec.Replicas - r.Client.Status().Update(context.TODO(), dc) + r.Client = makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) _ = r.reconcileStatusKeycloak(a) assert.Equal(t, "Running", a.Status.SSO) @@ -128,7 +147,13 @@ func TestReconcileArgoCD_reconcileStatusSSO(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - r := makeTestReconciler(t, test.argoCD) + resObjs := []client.Object{test.argoCD} + subresObjs := []client.Object{test.argoCD} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, test.argoCD.Namespace, "")) r.reconcileSSO(test.argoCD) @@ -179,10 +204,6 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { a.Spec.Server.Ingress.Enabled = test.ingressEnabled }) - objs := []runtime.Object{ - a, - } - route := &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ Name: testArgoCDName + "-server", @@ -215,12 +236,12 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { Namespace: testNamespace, }, Status: networkingv1.IngressStatus{ - LoadBalancer: v1.LoadBalancerStatus{ - Ingress: []v1.LoadBalancerIngress{ + LoadBalancer: networkingv1.IngressLoadBalancerStatus{ + Ingress: []networkingv1.IngressLoadBalancerIngress{ { IP: "12.0.0.1", Hostname: "argocd", - Ports: []v1.PortStatus{}, + Ports: []networkingv1.IngressPortStatus{}, }, { IP: "12.0.0.5", @@ -231,7 +252,13 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { }, } - r := makeReconciler(t, a, objs...) + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + if test.routeEnabled { err := r.Client.Create(context.TODO(), route) assert.NoError(t, err) @@ -253,7 +280,13 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { func TestReconcileArgoCD_reconcileStatusNotificationsController(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileStatusNotifications(a)) assert.Equal(t, "", a.Status.NotificationsController) @@ -272,7 +305,13 @@ func TestReconcileArgoCD_reconcileStatusNotificationsController(t *testing.T) { func TestReconcileArgoCD_reconcileStatusApplicationSetController(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) assert.NoError(t, r.reconcileStatusApplicationSetController(a)) assert.Equal(t, "Unknown", a.Status.ApplicationSetController) diff --git a/controllers/argocd/testing.go b/controllers/argocd/testing.go index 7c33d49f1..3f14ae7c9 100644 --- a/controllers/argocd/testing.go +++ b/controllers/argocd/testing.go @@ -31,12 +31,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/argoproj-labs/argocd-operator/controllers/argoutil" - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) @@ -50,16 +50,36 @@ func ZapLogger(development bool) logr.Logger { return zap.New(zap.UseDevMode(development)) } -func makeTestReconciler(t *testing.T, objs ...runtime.Object) *ReconcileArgoCD { - s := scheme.Scheme - assert.NoError(t, argoproj.AddToScheme(s)) - assert.NoError(t, argoprojv1alpha1.AddToScheme(s)) +type SchemeOpt func(*runtime.Scheme) error - cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() +func makeTestReconciler(client client.Client, sch *runtime.Scheme) *ReconcileArgoCD { return &ReconcileArgoCD{ - Client: cl, - Scheme: s, + Client: client, + Scheme: sch, + } +} + +func makeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client.Object, runtimeObj []runtime.Object) client.Client { + client := fake.NewClientBuilder().WithScheme(sch) + if len(resObjs) > 0 { + client = client.WithObjects(resObjs...) + } + if len(subresObjs) > 0 { + client = client.WithStatusSubresource(subresObjs...) + } + if len(runtimeObj) > 0 { + client = client.WithRuntimeObjects(runtimeObj...) } + return client.Build() +} + +func makeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { + s := scheme.Scheme + for _, opt := range sOpts { + _ = opt(s) + } + + return s } type argoCDOpt func(*argoproj.ArgoCD) diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index 17680c131..c740fd096 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -59,7 +59,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/source" ) var ( @@ -1050,22 +1049,22 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou tlsSecretHandler := handler.EnqueueRequestsFromMapFunc(tlsSecretMapper) - bldr.Watches(&source.Kind{Type: &v1.ClusterRoleBinding{}}, clusterResourceHandler) + bldr.Watches(&v1.ClusterRoleBinding{}, clusterResourceHandler) - bldr.Watches(&source.Kind{Type: &v1.ClusterRole{}}, clusterResourceHandler) + bldr.Watches(&v1.ClusterRole{}, clusterResourceHandler) - bldr.Watches(&source.Kind{Type: &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ + bldr.Watches(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ Name: common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, - }}}, appSetGitlabSCMTLSConfigMapHandler) + }}, appSetGitlabSCMTLSConfigMapHandler) // Watch for secrets of type TLS that might be created by external processes - bldr.Watches(&source.Kind{Type: &corev1.Secret{Type: corev1.SecretTypeTLS}}, tlsSecretHandler) + bldr.Watches(&corev1.Secret{Type: corev1.SecretTypeTLS}, tlsSecretHandler) // Watch for cluster secrets added to the argocd instance - bldr.Watches(&source.Kind{Type: &corev1.Secret{ObjectMeta: metav1.ObjectMeta{ + bldr.Watches(&corev1.Secret{ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ common.ArgoCDManagedByClusterArgoCDLabel: "cluster", - }}}}, clusterSecretResourceHandler) + }}}, clusterSecretResourceHandler) // Watch for changes to Secret sub-resources owned by ArgoCD instances. bldr.Owns(&appsv1.StatefulSet{}) @@ -1091,16 +1090,13 @@ func (r *ReconcileArgoCD) setResourceWatches(bldr *builder.Builder, clusterResou if IsTemplateAPIAvailable() { // Watch for the changes to Deployment Config - bldr.Watches(&source.Kind{Type: &oappsv1.DeploymentConfig{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &argoproj.ArgoCD{}, - }, - builder.WithPredicates(deploymentConfigPred)) + bldr.Owns(&oappsv1.DeploymentConfig{}, builder.WithPredicates(deploymentConfigPred)) + } namespaceHandler := handler.EnqueueRequestsFromMapFunc(namespaceResourceMapper) - bldr.Watches(&source.Kind{Type: &corev1.Namespace{}}, namespaceHandler, builder.WithPredicates(namespaceFilterPredicate())) + bldr.Watches(&corev1.Namespace{}, namespaceHandler, builder.WithPredicates(namespaceFilterPredicate())) return bldr } @@ -1244,10 +1240,7 @@ func namespaceFilterPredicate() predicate.Predicate { // if a namespace is deleted, remove it from deprecationEventEmissionTracker (if exists) so that if a namespace with the same name // is created in the future and contains an Argo CD instance, it will be tracked appropriately - if _, ok := DeprecationEventEmissionTracker[e.Object.GetName()]; ok { - delete(DeprecationEventEmissionTracker, e.Object.GetName()) - } - + delete(DeprecationEventEmissionTracker, e.Object.GetName()) return false }, } @@ -1405,7 +1398,7 @@ func (r *ReconcileArgoCD) setManagedSourceNamespaces(cr *argoproj.ArgoCD) error // It also removes the managed-by-cluster-argocd label from the namespace func (r *ReconcileArgoCD) removeUnmanagedSourceNamespaceResources(cr *argoproj.ArgoCD) error { - for ns, _ := range r.ManagedSourceNamespaces { + for ns := range r.ManagedSourceNamespaces { managedNamespace := false if cr.GetDeletionTimestamp() == nil { for _, namespace := range cr.Spec.SourceNamespaces { @@ -1456,7 +1449,7 @@ func (r *ReconcileArgoCD) cleanupUnmanagedSourceNamespaceResources(cr *argoproj. } // Delete RoleBindings for SourceNamespaces existingRoleBinding := &v1.RoleBinding{} - roleBindingName := getRoleBindingNameForSourceNamespaces(cr.Name, cr.Namespace, namespace.Name) + roleBindingName := getRoleBindingNameForSourceNamespaces(cr.Name, namespace.Name) if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: roleBindingName, Namespace: namespace.Name}, existingRoleBinding); err != nil { if !errors.IsNotFound(err) { return fmt.Errorf("failed to get the rolebinding associated with %s : %s", common.ArgoCDServerComponent, err) diff --git a/controllers/argocd/util_test.go b/controllers/argocd/util_test.go index d028dc74f..019b2c442 100644 --- a/controllers/argocd/util_test.go +++ b/controllers/argocd/util_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -16,6 +17,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" testclient "k8s.io/client-go/kubernetes/fake" ) @@ -238,7 +240,14 @@ func TestGetArgoServerURI(t *testing.T) { func TestRemoveDeletionFinalizer(t *testing.T) { t.Run("ArgoCD resource present", func(t *testing.T) { a := makeTestArgoCD(addFinalizer(common.ArgoCDDeletionFinalizer)) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := r.removeDeletionFinalizer(a) assert.NoError(t, err) if a.IsDeletionFinalizerPresent() { @@ -247,7 +256,14 @@ func TestRemoveDeletionFinalizer(t *testing.T) { }) t.Run("ArgoCD resource absent", func(t *testing.T) { a := makeTestArgoCD(addFinalizer(common.ArgoCDDeletionFinalizer)) - r := makeTestReconciler(t) + + resObjs := []client.Object{} + subresObjs := []client.Object{} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := r.removeDeletionFinalizer(a) assert.Error(t, err, `failed to remove deletion finalizer from argocd: argocds.argoproj.io "argocd" not found`) }) @@ -256,7 +272,14 @@ func TestRemoveDeletionFinalizer(t *testing.T) { func TestAddDeletionFinalizer(t *testing.T) { t.Run("ArgoCD resource present", func(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := r.addDeletionFinalizer(a) assert.NoError(t, err) if !a.IsDeletionFinalizerPresent() { @@ -265,7 +288,14 @@ func TestAddDeletionFinalizer(t *testing.T) { }) t.Run("ArgoCD resource absent", func(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t) + + resObjs := []client.Object{} + subresObjs := []client.Object{} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + err := r.addDeletionFinalizer(a) assert.Error(t, err, `failed to add deletion finalizer for argocd: argocds.argoproj.io "argocd" not found`) }) @@ -482,7 +512,14 @@ func TestRemoveManagedNamespaceFromClusterSecretAfterDeletion(t *testing.T) { func TestRemoveManagedByLabelFromNamespaces(t *testing.T) { a := makeTestArgoCD() - r := makeTestReconciler(t) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + nsArgocd := &v1.Namespace{ObjectMeta: metav1.ObjectMeta{ Name: a.Namespace, }} @@ -538,40 +575,47 @@ func TestRemoveManagedByLabelFromNamespaces(t *testing.T) { func TestSetManagedNamespaces(t *testing.T) { a := makeTestArgoCD() - nsList := &v1.NamespaceList{ - Items: []v1.Namespace{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "test-namespace-1", - Labels: map[string]string{ - common.ArgoCDManagedByLabel: testNamespace, - }, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "test-namespace-2", - Labels: map[string]string{ - common.ArgoCDManagedByLabel: testNamespace, - }, - }, + + ns1 := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-namespace-1", + Labels: map[string]string{ + common.ArgoCDManagedByLabel: testNamespace, }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "test-namespace-3", - Labels: map[string]string{ - common.ArgoCDManagedByLabel: "random-namespace", - }, - }, + }, + } + + ns2 := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-namespace-2", + Labels: map[string]string{ + common.ArgoCDManagedByLabel: testNamespace, }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "test-namespace-4", - }, + }, + } + + ns3 := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-namespace-3", + Labels: map[string]string{ + common.ArgoCDManagedByLabel: "random-namespace", }, }, } - r := makeTestReconciler(t, nsList) + + ns4 := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-namespace-4", + }, + } + + resObjs := []client.Object{a, &ns1, &ns2, &ns3, &ns4} + + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.setManagedNamespaces(a) assert.NoError(t, err) @@ -591,19 +635,21 @@ func TestSetManagedSourceNamespaces(t *testing.T) { "test-namespace-1", }, } - nsList := &v1.NamespaceList{ - Items: []v1.Namespace{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "test-namespace-1", - Labels: map[string]string{ - common.ArgoCDManagedByClusterArgoCDLabel: testNamespace, - }, - }, + ns1 := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-namespace-1", + Labels: map[string]string{ + common.ArgoCDManagedByClusterArgoCDLabel: testNamespace, }, }, } - r := makeTestReconciler(t, nsList) + + resObjs := []client.Object{a, &ns1} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) err := r.setManagedSourceNamespaces(a) assert.NoError(t, err) @@ -649,7 +695,14 @@ func TestReconcileArgoCD_reconcileDexOAuthClientSecret(t *testing.T) { }, } }) - r := makeTestReconciler(t, a) + + resObjs := []client.Object{a} + subresObjs := []client.Object{a} + runtimeObjs := []runtime.Object{} + sch := makeTestReconcilerScheme(argoproj.AddToScheme) + cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) + r := makeTestReconciler(cl, sch) + assert.NoError(t, createNamespace(r, a.Namespace, "")) _, err := r.reconcileServiceAccount(common.ArgoCDDefaultDexServiceAccountName, a) assert.NoError(t, err) diff --git a/controllers/suite_testx.go b/controllers/suite_testx.go index b01089301..59ad0bd9e 100644 --- a/controllers/suite_testx.go +++ b/controllers/suite_testx.go @@ -18,14 +18,12 @@ package controllers import ( "path/filepath" - "testing" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/envtest/printer" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -41,14 +39,6 @@ import ( var k8sClient client.Client var testEnv *envtest.Environment -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecsWithDefaultAndCustomReporters(t, - "Controller Suite", - []Reporter{printer.NewlineReporter{}}) -} - var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml index 8a8b0b0f1..33c64ec9f 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocdexports.yaml @@ -54,20 +54,23 @@ spec: description: PVC is the desired characteristics for a PersistentVolumeClaim. properties: accessModes: - description: 'AccessModes contains the desired access modes + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify either: * - An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + description: 'dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always have the - same contents as the DataSourceRef field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will be copied + to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not + be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the resource being @@ -86,26 +89,32 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which to populate - the volume with data, if a non-empty volume is desired. - This may be any local object from a non-empty API group - (non core object) or a PersistentVolumeClaim object. When - this field is specified, volume binding will only succeed + description: 'dataSourceRef specifies the object from which + to populate the volume with data, if a non-empty volume + is desired. This may be any object from a non-empty API + group (non core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will - replace the functionality of the DataSource field and as + replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same - value. For backwards compatibility, both fields (DataSource - and DataSourceRef) will be set to the same value automatically - if one of them is empty and the other is non-empty. There - are two important differences between DataSource and DataSourceRef: - * While DataSource only allows two specific types of objects, - DataSourceRef allows any non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed values (dropping - them), DataSourceRef preserves all values, and generates - an error if a disallowed value is specified. (Alpha) Using - this field requires the AnyVolumeDataSource feature gate - to be enabled.' + value. For backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource and + dataSourceRef) will be set to the same value automatically + if one of them is empty and the other is non-empty. When + namespace is specified in dataSourceRef, dataSource isn''t + set to the same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, + dataSourceRef allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and generates + an error if a disallowed value is specified. * While dataSource + only allows local objects, dataSourceRef allows objects in + any namespaces. (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the resource being @@ -119,18 +128,50 @@ spec: name: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace of resource being + referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object is + required in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource feature gate to be + enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum resources the + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -152,11 +193,12 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider for binding. + description: selector is a label query over volumes to consider + for binding. properties: matchExpressions: description: matchExpressions is a list of label selector @@ -201,8 +243,8 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required by the claim. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of volume is required @@ -210,7 +252,7 @@ spec: in claim spec. type: string volumeName: - description: VolumeName is the binding reference to the PersistentVolume + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index f0a7218e7..e8ba59f6c 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -189,6 +189,28 @@ spec: description: Resources defines the Compute Resources required by the container for ApplicationSet. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -209,7 +231,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -252,12 +275,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -265,13 +288,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -525,6 +548,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Application Controller. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -545,7 +590,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sharding: @@ -608,6 +654,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -628,7 +696,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -696,10 +765,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -709,13 +778,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -726,6 +795,28 @@ spec: description: Resources defines the Compute Resources required by the container for Grafana. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -746,7 +837,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -850,6 +942,28 @@ spec: description: Resources defines the Compute Resources required by the container for HA. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -870,7 +984,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object required: @@ -1139,6 +1254,28 @@ spec: description: Resources defines the Compute Resources required by the container for Argo CD Notifications. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -1159,7 +1296,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -1211,10 +1349,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -1224,13 +1362,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -1363,6 +1501,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -1383,7 +1543,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -1534,11 +1695,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -1549,7 +1710,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -1725,7 +1886,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -1780,7 +1941,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -1879,7 +2043,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -1961,8 +2128,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -1994,7 +2160,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2091,13 +2259,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -2169,8 +2337,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -2202,7 +2369,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2292,10 +2461,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -2317,9 +2530,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -2444,7 +2678,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -2477,15 +2712,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -2534,8 +2765,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -2567,7 +2797,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -2795,6 +3027,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -2815,7 +3069,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object serviceaccount: @@ -2830,11 +3085,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -2845,7 +3100,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -3021,7 +3276,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -3076,7 +3331,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -3175,7 +3433,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -3257,8 +3518,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3290,7 +3550,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -3387,13 +3649,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -3465,8 +3727,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3498,7 +3759,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -3588,10 +3851,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -3613,9 +3920,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -3740,7 +4068,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -3773,15 +4102,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -3830,8 +4155,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -3863,7 +4187,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -4124,122 +4450,124 @@ spec: may be accessed by any container in the pod. properties: awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' format: int32 type: integer readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: boolean volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: string required: - volumeID type: object azureDisk: - description: AzureDisk represents an Azure Data Disk mount + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. properties: cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' type: string diskName: - description: The Name of the data disk in the blob storage + description: diskName is the Name of the data disk in + the blob storage type: string diskURI: - description: The URI the data disk in the blob storage + description: diskURI is the URI of data disk in the + blob storage type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults to shared' type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean required: - diskName - diskURI type: object azureFile: - description: AzureFile represents an Azure File Service + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. properties: readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretName: - description: the name of secret that contains Azure - Storage Account Name and Key + description: secretName is the name of secret that + contains Azure Storage Account Name and Key type: string shareName: - description: Share Name + description: shareName is the azure share Name type: string required: - secretName - shareName type: object cephfs: - description: CephFS represents a Ceph FS mount on the host + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime properties: monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' items: type: string type: array path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' type: string readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: boolean secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4248,30 +4576,30 @@ spec: type: string type: object user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string required: - monitors type: object cinder: - description: 'Cinder represents a cinder volume attached + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string readOnly: - description: 'Optional: Defaults to false (read/write). + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: boolean secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4280,37 +4608,38 @@ spec: type: string type: object volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string required: - volumeID type: object configMap: - description: ConfigMap represents a configMap that should + description: configMap represents a configMap that should populate this volume properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: @@ -4318,26 +4647,26 @@ spec: volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -4349,28 +4678,28 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: - description: Specify whether the ConfigMap or its keys - must be defined + description: optional specify whether the ConfigMap + or its keys must be defined type: boolean type: object csi: - description: CSI (Container Storage Interface) represents + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). properties: driver: - description: Driver is the name of the CSI driver that + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. type: string fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. type: string nodePublishSecretRef: - description: NodePublishSecretRef is a reference to + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, @@ -4385,13 +4714,13 @@ spec: type: string type: object readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). type: boolean volumeAttributes: additionalProperties: type: string - description: VolumeAttributes stores driver-specific + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. type: object @@ -4399,7 +4728,7 @@ spec: - driver type: object downwardAPI: - description: DownwardAPI represents downward API about the + description: downwardAPI represents downward API about the pod that should populate this volume properties: defaultMode: @@ -4489,31 +4818,33 @@ spec: type: array type: object emptyDir: - description: 'EmptyDir represents a temporary directory + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' properties: medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' type: string sizeLimit: anyOf: - type: integer - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object ephemeral: - description: "Ephemeral represents a volume that is handled + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n @@ -4569,24 +4900,27 @@ spec: also valid here. properties: accessModes: - description: 'AccessModes contains the desired + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the @@ -4608,32 +4942,41 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the @@ -4650,12 +4993,23 @@ spec: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than @@ -4663,6 +5017,32 @@ spec: capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -4686,12 +5066,13 @@ spec: If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider - for binding. + description: selector is a label query over + volumes to consider for binding. properties: matchExpressions: description: matchExpressions is a list @@ -4742,8 +5123,9 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of @@ -4752,7 +5134,7 @@ spec: claim spec. type: string volumeName: - description: VolumeName is the binding reference + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object @@ -4761,32 +5143,34 @@ spec: type: object type: object fc: - description: FC represents a Fibre Channel resource that + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' type: string lun: - description: 'Optional: FC target lun number' + description: 'lun is Optional: FC target lun number' format: int32 type: integer readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' items: type: string type: array wwids: - description: 'Optional: FC volume world wide identifiers + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' items: @@ -4794,35 +5178,37 @@ spec: type: array type: object flexVolume: - description: FlexVolume represents a generic volume resource + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. properties: driver: - description: Driver is the name of the driver to use + description: driver is the name of the driver to use for this volume. type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. type: string options: additionalProperties: type: string - description: 'Optional: Extra command options if any.' + description: 'options is Optional: this field holds + extra command options if any.' type: object readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -4834,49 +5220,50 @@ spec: - driver type: object flocker: - description: Flocker represents a Flocker volume attached + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated type: string datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset type: string type: object gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' format: int32 type: integer pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: boolean @@ -4884,42 +5271,43 @@ spec: - pdName type: object gitRepo: - description: 'GitRepo represents a git repository at a particular + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' properties: directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. type: string repository: - description: Repository URL + description: repository is the URL type: string revision: - description: Commit hash for the specified revision. + description: revision is the commit hash for the specified + revision. type: string required: - repository type: object glusterfs: - description: 'Glusterfs represents a Glusterfs mount on + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' properties: endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string path: - description: 'Path is the Glusterfs volume path. More + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string readOnly: - description: 'ReadOnly here will force the Glusterfs + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: boolean @@ -4928,7 +5316,7 @@ spec: - path type: object hostPath: - description: 'HostPath represents a pre-existing file or + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the @@ -4939,68 +5327,71 @@ spec: as read/write.' properties: path: - description: 'Path of the directory on the host. If + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string type: - description: 'Type for HostPath Volume Defaults to "" + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string required: - path type: object iscsi: - description: 'ISCSI represents an ISCSI Disk resource that + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' properties: chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication type: boolean chapAuthSession: - description: whether support iSCSI Session CHAP authentication + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication type: boolean fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' type: string initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. type: string iqn: - description: Target iSCSI Qualified Name. + description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). type: string lun: - description: iSCSI Target Lun number. + description: lun represents iSCSI Target Lun number. format: int32 type: integer portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). items: type: string type: array readOnly: - description: ReadOnly here will force the ReadOnly setting + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. type: boolean secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -5009,9 +5400,10 @@ spec: type: string type: object targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). type: string required: - iqn @@ -5019,24 +5411,24 @@ spec: - targetPortal type: object name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string nfs: - description: 'NFS represents an NFS mount on the host that + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' properties: path: - description: 'Path that is exported by the NFS server. + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string readOnly: - description: 'ReadOnly here will force the NFS export + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: boolean server: - description: 'Server is the hostname or IP address of + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string required: @@ -5044,89 +5436,89 @@ spec: - server type: object persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' properties: claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' type: string readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. type: boolean required: - claimName type: object photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string pdID: - description: ID that identifies Photon Controller persistent - disk + description: pdID is the ID that identifies Photon Controller + persistent disk type: string required: - pdID type: object portworxVolume: - description: PortworxVolume represents a portworx volume + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine properties: fsType: - description: FSType represents the filesystem type to + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean volumeID: - description: VolumeID uniquely identifies a Portworx + description: volumeID uniquely identifies a Portworx volume type: string required: - volumeID type: object projected: - description: Items for all in one resources secrets, configmaps, - and downward API + description: projected items for all in one resources secrets, + configmaps, and downward API properties: defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. format: int32 type: integer sources: - description: list of volume projections + description: sources is the list of volume projections items: description: Projection that may be projected along with other supported volume types properties: configMap: - description: information about the configMap data - to project + description: configMap information about the configMap + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content @@ -5143,27 +5535,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -5179,13 +5571,13 @@ spec: kind, uid?' type: string optional: - description: Specify whether the ConfigMap - or its keys must be defined + description: optional specify whether the + ConfigMap or its keys must be defined type: boolean type: object downwardAPI: - description: information about the downwardAPI - data to project + description: downwardAPI information about the + downwardAPI data to project properties: items: description: Items is a list of DownwardAPIVolume @@ -5269,11 +5661,11 @@ spec: type: array type: object secret: - description: information about the secret data - to project + description: secret information about the secret + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content @@ -5290,27 +5682,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -5326,16 +5718,16 @@ spec: kind, uid?' type: string optional: - description: Specify whether the Secret or - its key must be defined + description: optional field specify whether + the Secret or its key must be defined type: boolean type: object serviceAccountToken: - description: information about the serviceAccountToken - data to project + description: serviceAccountToken is information + about the serviceAccountToken data to project properties: audience: - description: Audience is the intended audience + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise @@ -5343,7 +5735,7 @@ spec: to the identifier of the apiserver. type: string expirationSeconds: - description: ExpirationSeconds is the requested + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively @@ -5356,7 +5748,7 @@ spec: format: int64 type: integer path: - description: Path is the path relative to + description: path is the path relative to the mount point of the file to project the token into. type: string @@ -5367,35 +5759,35 @@ spec: type: array type: object quobyte: - description: Quobyte represents a Quobyte mount on the host + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime properties: group: - description: Group to map volume access to Default is + description: group to map volume access to Default is no group type: string readOnly: - description: ReadOnly here will force the Quobyte volume + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. type: boolean registry: - description: Registry represents a single or multiple + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes type: string tenant: - description: Tenant owning the given Quobyte volume + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin type: string user: - description: User to map volume access to Defaults to + description: user to map volume access to Defaults to serivceaccount user type: string volume: - description: Volume is a string that references an already + description: volume is a string that references an already created Quobyte volume by name. type: string required: @@ -5403,43 +5795,44 @@ spec: - volume type: object rbd: - description: 'RBD represents a Rados Block Device mount + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' type: string image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string keyring: - description: 'Keyring is the path to key ring for RBDUser. + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' items: type: string type: array pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: boolean secretRef: - description: 'SecretRef is name of the authentication + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' properties: @@ -5450,35 +5843,36 @@ spec: type: string type: object user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string required: - image - monitors type: object scaleIO: - description: ScaleIO represents a ScaleIO persistent volume + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". type: string gateway: - description: The host address of the ScaleIO API Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef references to the secret for + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. properties: @@ -5489,26 +5883,26 @@ spec: type: string type: object sslEnabled: - description: Flag to enable/disable SSL communication + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false type: boolean storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. type: string storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. type: string system: - description: The name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system + as configured in ScaleIO. type: string volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. type: string required: - gateway @@ -5516,57 +5910,58 @@ spec: - system type: object secret: - description: 'Secret represents a secret that should populate + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -5574,30 +5969,30 @@ spec: type: object type: array optional: - description: Specify whether the Secret or its keys - must be defined + description: optional field specify whether the Secret + or its keys must be defined type: boolean secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' type: string type: object storageos: - description: StorageOS represents a StorageOS volume attached + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef specifies the secret to use for + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. properties: @@ -5608,12 +6003,12 @@ spec: type: string type: object volumeName: - description: VolumeName is the human-readable name of + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. type: string volumeNamespace: - description: VolumeNamespace specifies the scope of + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within @@ -5625,25 +6020,26 @@ spec: type: string type: object vsphereVolume: - description: VsphereVolume represents a vSphere volume attached + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. type: string volumePath: - description: Path that identifies vSphere volume vmdk + description: volumePath is the path that identifies + vSphere volume vmdk type: string required: - volumePath @@ -5764,8 +6160,9 @@ spec: for the Argo CD Server component. properties: maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. format: int32 type: integer minReplicas: @@ -5784,23 +6181,26 @@ spec: Scale subresource. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the + referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. format: int32 type: integer required: @@ -5964,12 +6364,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -5977,13 +6377,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -6022,10 +6422,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -6035,13 +6435,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -6071,6 +6471,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Argo CD server component. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6091,7 +6513,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -6211,6 +6634,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6232,7 +6677,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -6254,6 +6699,28 @@ spec: description: Resources defines the Compute Resources required by the container for Keycloak. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6275,7 +6742,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object rootCA: @@ -6298,6 +6765,28 @@ spec: Resources defines the Compute Resources required by the container for SSO. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6318,7 +6807,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object verifyTLS: @@ -6632,6 +7122,28 @@ spec: description: Resources defines the Compute Resources required by the container for ApplicationSet. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6652,7 +7164,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object scmRootCAConfigMap: @@ -6700,12 +7213,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -6713,13 +7226,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -6973,6 +7486,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Application Controller. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -6993,7 +7528,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object sharding: @@ -7093,10 +7629,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -7106,13 +7642,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -7123,6 +7659,28 @@ spec: description: Resources defines the Compute Resources required by the container for Grafana. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7143,7 +7701,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -7247,6 +7806,28 @@ spec: description: Resources defines the Compute Resources required by the container for HA. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7267,7 +7848,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object required: @@ -7536,6 +8118,28 @@ spec: description: Resources defines the Compute Resources required by the container for Argo CD Notifications. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7556,7 +8160,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -7608,10 +8213,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -7621,13 +8226,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -7760,6 +8365,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -7780,7 +8407,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -7931,11 +8559,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -7946,7 +8574,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -8122,7 +8750,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -8177,7 +8805,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -8276,7 +8907,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -8358,8 +8992,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8391,7 +9024,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -8488,13 +9123,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -8566,8 +9201,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8599,7 +9233,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -8689,10 +9325,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -8714,9 +9394,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -8841,7 +9542,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -8874,15 +9576,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -8931,8 +9629,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -8964,7 +9661,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9192,6 +9891,28 @@ spec: description: Resources defines the Compute Resources required by the container for Redis. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -9212,7 +9933,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object serviceaccount: @@ -9227,11 +9949,11 @@ spec: run within a pod. properties: args: - description: 'Arguments to the entrypoint. The docker image''s - CMD is used if this is not provided. Variable references - $(VAR_NAME) are expanded using the container''s environment. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, @@ -9242,7 +9964,7 @@ spec: type: array command: description: 'Entrypoint array. Not executed within a shell. - The docker image''s ENTRYPOINT is used if this is not + The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be @@ -9418,7 +10140,7 @@ spec: type: object type: array image: - description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' @@ -9473,7 +10195,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -9572,7 +10297,10 @@ spec: header to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. type: string value: description: The header field value @@ -9654,8 +10382,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -9687,7 +10414,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9784,13 +10513,13 @@ spec: type: string ports: description: List of ports to expose from the container. - Exposing a port here gives the system additional information - about the network connections a container uses, but is - primarily informational. Not specifying a port here DOES - NOT prevent that port from being exposed. Any port which - is listening on the default "0.0.0.0" address inside a - container will be accessible from the network. Cannot - be updated. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. items: description: ContainerPort represents a network port in a single container. @@ -9862,8 +10591,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -9895,7 +10623,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -9985,10 +10715,54 @@ spec: format: int32 type: integer type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic resources: description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -10010,9 +10784,30 @@ spec: of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string securityContext: description: 'SecurityContext defines the security options the container should be run with. If set, the fields of @@ -10137,7 +10932,8 @@ spec: The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. - Must only be set if type is "Localhost". + Must be set if type is "Localhost". Must NOT be + set for any other type. type: string type: description: "type indicates which kind of seccomp @@ -10170,15 +10966,11 @@ spec: type: string hostProcess: description: HostProcess determines if a container - should be run as a 'Host Process' container. This - field is alpha-level and will only be honored - by components that enable the WindowsHostProcessContainers - feature flag. Setting this field without the feature - flag will result in errors when validating the - Pod. All of a Pod's containers must have the same - effective HostProcess value (it is not allowed - to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork must also be set to true. type: boolean runAsUserName: @@ -10227,8 +11019,7 @@ spec: type: integer grpc: description: GRPC specifies an action involving a GRPC - port. This is an alpha field and requires enabling - GRPCContainerProbe feature gate. + port. properties: port: description: Port number of the gRPC service. Number @@ -10260,7 +11051,9 @@ spec: to be used in HTTP probes properties: name: - description: The header field name + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. type: string value: description: The header field value @@ -10521,122 +11314,124 @@ spec: may be accessed by any container in the pod. properties: awsElasticBlockStore: - description: 'AWSElasticBlockStore represents an AWS Disk + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty).' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' format: int32 type: integer readOnly: - description: 'Specify "true" to force and set the ReadOnly - property in VolumeMounts to "true". If omitted, the - default is "false". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: boolean volumeID: - description: 'Unique ID of the persistent disk resource - in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' type: string required: - volumeID type: object azureDisk: - description: AzureDisk represents an Azure Data Disk mount + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. properties: cachingMode: - description: 'Host Caching mode: None, Read Only, Read - Write.' + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' type: string diskName: - description: The Name of the data disk in the blob storage + description: diskName is the Name of the data disk in + the blob storage type: string diskURI: - description: The URI the data disk in the blob storage + description: diskURI is the URI of data disk in the + blob storage type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string kind: - description: 'Expected values Shared: multiple blob - disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults to shared' type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean required: - diskName - diskURI type: object azureFile: - description: AzureFile represents an Azure File Service + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. properties: readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretName: - description: the name of secret that contains Azure - Storage Account Name and Key + description: secretName is the name of secret that + contains Azure Storage Account Name and Key type: string shareName: - description: Share Name + description: shareName is the azure share Name type: string required: - secretName - shareName type: object cephfs: - description: CephFS represents a Ceph FS mount on the host + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime properties: monitors: - description: 'Required: Monitors is a collection of - Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' items: type: string type: array path: - description: 'Optional: Used as the mounted root, rather - than the full Ceph tree, default is /' + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' type: string readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: boolean secretFile: - description: 'Optional: SecretFile is the path to key - ring for User, default is /etc/ceph/user.secret More - info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string secretRef: - description: 'Optional: SecretRef is reference to the - authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -10645,30 +11440,30 @@ spec: type: string type: object user: - description: 'Optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' type: string required: - monitors type: object cinder: - description: 'Cinder represents a cinder volume attached + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string readOnly: - description: 'Optional: Defaults to false (read/write). + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: boolean secretRef: - description: 'Optional: points to a secret object containing - parameters used to connect to OpenStack.' + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -10677,37 +11472,38 @@ spec: type: string type: object volumeID: - description: 'volume id used to identify the volume - in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' type: string required: - volumeID type: object configMap: - description: ConfigMap represents a configMap that should + description: configMap represents a configMap that should populate this volume properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be - projected into the volume as a file whose name is - the key and content is the value. If specified, the - listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is - specified which is not present in the ConfigMap, the - volume setup will error unless it is marked optional. + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. items: @@ -10715,26 +11511,26 @@ spec: volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -10746,28 +11542,28 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string optional: - description: Specify whether the ConfigMap or its keys - must be defined + description: optional specify whether the ConfigMap + or its keys must be defined type: boolean type: object csi: - description: CSI (Container Storage Interface) represents + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). properties: driver: - description: Driver is the name of the CSI driver that + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. type: string fsType: - description: Filesystem type to mount. Ex. "ext4", "xfs", - "ntfs". If not provided, the empty value is passed - to the associated CSI driver which will determine - the default filesystem to apply. + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. type: string nodePublishSecretRef: - description: NodePublishSecretRef is a reference to + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, @@ -10782,13 +11578,13 @@ spec: type: string type: object readOnly: - description: Specifies a read-only configuration for - the volume. Defaults to false (read/write). + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). type: boolean volumeAttributes: additionalProperties: type: string - description: VolumeAttributes stores driver-specific + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. type: object @@ -10796,7 +11592,7 @@ spec: - driver type: object downwardAPI: - description: DownwardAPI represents downward API about the + description: downwardAPI represents downward API about the pod that should populate this volume properties: defaultMode: @@ -10886,31 +11682,33 @@ spec: type: array type: object emptyDir: - description: 'EmptyDir represents a temporary directory + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' properties: medium: - description: 'What type of storage medium should back - this directory. The default is "" which means to use - the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' type: string sizeLimit: anyOf: - type: integer - type: string - description: 'Total amount of local storage required - for this EmptyDir volume. The size limit is also applicable - for memory medium. The maximum usage on memory medium - EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all - containers in a pod. The default is nil which means - that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object ephemeral: - description: "Ephemeral represents a volume that is handled + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n @@ -10966,24 +11764,27 @@ spec: also valid here. properties: accessModes: - description: 'AccessModes contains the desired + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' items: type: string type: array dataSource: - description: 'This field can be used to specify - either: * An existing VolumeSnapshot object - (snapshot.storage.k8s.io/VolumeSnapshot) * - An existing PVC (PersistentVolumeClaim) If - the provisioner or an external controller + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents - of the specified data source. If the AnyVolumeDataSource - feature gate is enabled, this field will always - have the same contents as the DataSourceRef - field.' + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' properties: apiGroup: description: APIGroup is the group for the @@ -11005,32 +11806,41 @@ spec: - name type: object dataSourceRef: - description: 'Specifies the object from which - to populate the volume with data, if a non-empty - volume is desired. This may be any local object - from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this - field is specified, volume binding will only - succeed if the type of the specified object - matches some installed volume populator or - dynamic provisioner. This field will replace - the functionality of the DataSource field + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards - compatibility, both fields (DataSource and - DataSourceRef) will be set to the same value - automatically if one of them is empty and - the other is non-empty. There are two important - differences between DataSource and DataSourceRef: - * While DataSource only allows two specific - types of objects, DataSourceRef allows any - non-core object, as well as PersistentVolumeClaim - objects. * While DataSource ignores disallowed - values (dropping them), DataSourceRef preserves + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed - value is specified. (Alpha) Using this field - requires the AnyVolumeDataSource feature gate - to be enabled.' + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' properties: apiGroup: description: APIGroup is the group for the @@ -11047,12 +11857,23 @@ spec: description: Name is the name of resource being referenced type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string required: - kind - name type: object resources: - description: 'Resources represents the minimum + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than @@ -11060,6 +11881,32 @@ spec: capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -11083,12 +11930,13 @@ spec: If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined - value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object selector: - description: A label query over volumes to consider - for binding. + description: selector is a label query over + volumes to consider for binding. properties: matchExpressions: description: matchExpressions is a list @@ -11139,8 +11987,9 @@ spec: type: object type: object storageClassName: - description: 'Name of the StorageClass required - by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' type: string volumeMode: description: volumeMode defines what type of @@ -11149,7 +11998,7 @@ spec: claim spec. type: string volumeName: - description: VolumeName is the binding reference + description: volumeName is the binding reference to the PersistentVolume backing this claim. type: string type: object @@ -11158,32 +12007,34 @@ spec: type: object type: object fc: - description: FC represents a Fibre Channel resource that + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. properties: fsType: - description: 'Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' type: string lun: - description: 'Optional: FC target lun number' + description: 'lun is Optional: FC target lun number' format: int32 type: integer readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean targetWWNs: - description: 'Optional: FC target worldwide names (WWNs)' + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' items: type: string type: array wwids: - description: 'Optional: FC volume world wide identifiers + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' items: @@ -11191,35 +12042,37 @@ spec: type: array type: object flexVolume: - description: FlexVolume represents a generic volume resource + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. properties: driver: - description: Driver is the name of the driver to use + description: driver is the name of the driver to use for this volume. type: string fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". The default filesystem depends on FlexVolume - script. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. type: string options: additionalProperties: type: string - description: 'Optional: Extra command options if any.' + description: 'options is Optional: this field holds + extra command options if any.' type: object readOnly: - description: 'Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' type: boolean secretRef: - description: 'Optional: SecretRef is reference to the - secret object containing sensitive information to - pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the - plugin scripts.' + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -11231,49 +12084,50 @@ spec: - driver type: object flocker: - description: Flocker represents a Flocker volume attached + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running properties: datasetName: - description: Name of the dataset stored as metadata - -> name on the dataset for Flocker should be considered - as deprecated + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated type: string datasetUUID: - description: UUID of the dataset. This is unique identifier - of a Flocker dataset + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset type: string type: object gcePersistentDisk: - description: 'GCEPersistentDisk represents a GCE Disk resource + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' type: string partition: - description: 'The partition in the volume that you want - to mount. If omitted, the default is to mount by volume - name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property - empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' format: int32 type: integer pdName: - description: 'Unique name of the PD resource in GCE. - Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' type: boolean @@ -11281,42 +12135,43 @@ spec: - pdName type: object gitRepo: - description: 'GitRepo represents a git repository at a particular + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' properties: directory: - description: Target directory name. Must not contain - or start with '..'. If '.' is supplied, the volume - directory will be the git repository. Otherwise, + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. type: string repository: - description: Repository URL + description: repository is the URL type: string revision: - description: Commit hash for the specified revision. + description: revision is the commit hash for the specified + revision. type: string required: - repository type: object glusterfs: - description: 'Glusterfs represents a Glusterfs mount on + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' properties: endpoints: - description: 'EndpointsName is the endpoint name that - details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string path: - description: 'Path is the Glusterfs volume path. More + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: string readOnly: - description: 'ReadOnly here will force the Glusterfs + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' type: boolean @@ -11325,7 +12180,7 @@ spec: - path type: object hostPath: - description: 'HostPath represents a pre-existing file or + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the @@ -11336,68 +12191,71 @@ spec: as read/write.' properties: path: - description: 'Path of the directory on the host. If + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string type: - description: 'Type for HostPath Volume Defaults to "" + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' type: string required: - path type: object iscsi: - description: 'ISCSI represents an ISCSI Disk resource that + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' properties: chapAuthDiscovery: - description: whether support iSCSI Discovery CHAP authentication + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication type: boolean chapAuthSession: - description: whether support iSCSI Session CHAP authentication + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication type: boolean fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' type: string initiatorName: - description: Custom iSCSI Initiator Name. If initiatorName - is specified with iscsiInterface simultaneously, new - iSCSI interface : will - be created for the connection. + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. type: string iqn: - description: Target iSCSI Qualified Name. + description: iqn is the target iSCSI Qualified Name. type: string iscsiInterface: - description: iSCSI Interface Name that uses an iSCSI - transport. Defaults to 'default' (tcp). + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). type: string lun: - description: iSCSI Target Lun number. + description: lun represents iSCSI Target Lun number. format: int32 type: integer portals: - description: iSCSI Target Portal List. The portal is - either an IP or ip_addr:port if the port is other - than default (typically TCP ports 860 and 3260). + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). items: type: string type: array readOnly: - description: ReadOnly here will force the ReadOnly setting + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. type: boolean secretRef: - description: CHAP Secret for iSCSI target and initiator - authentication + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication properties: name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names @@ -11406,9 +12264,10 @@ spec: type: string type: object targetPortal: - description: iSCSI Target Portal. The Portal is either - an IP or ip_addr:port if the port is other than default - (typically TCP ports 860 and 3260). + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). type: string required: - iqn @@ -11416,24 +12275,24 @@ spec: - targetPortal type: object name: - description: 'Volume''s name. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string nfs: - description: 'NFS represents an NFS mount on the host that + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' properties: path: - description: 'Path that is exported by the NFS server. + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string readOnly: - description: 'ReadOnly here will force the NFS export + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: boolean server: - description: 'Server is the hostname or IP address of + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' type: string required: @@ -11441,89 +12300,89 @@ spec: - server type: object persistentVolumeClaim: - description: 'PersistentVolumeClaimVolumeSource represents + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' properties: claimName: - description: 'ClaimName is the name of a PersistentVolumeClaim + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' type: string readOnly: - description: Will force the ReadOnly setting in VolumeMounts. - Default false. + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. type: boolean required: - claimName type: object photonPersistentDisk: - description: PhotonPersistentDisk represents a PhotonController + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string pdID: - description: ID that identifies Photon Controller persistent - disk + description: pdID is the ID that identifies Photon Controller + persistent disk type: string required: - pdID type: object portworxVolume: - description: PortworxVolume represents a portworx volume + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine properties: fsType: - description: FSType represents the filesystem type to + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean volumeID: - description: VolumeID uniquely identifies a Portworx + description: volumeID uniquely identifies a Portworx volume type: string required: - volumeID type: object projected: - description: Items for all in one resources secrets, configmaps, - and downward API + description: projected items for all in one resources secrets, + configmaps, and downward API properties: defaultMode: - description: Mode bits used to set permissions on created - files by default. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. Directories within the - path are not affected by this setting. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set. + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. format: int32 type: integer sources: - description: list of volume projections + description: sources is the list of volume projections items: description: Projection that may be projected along with other supported volume types properties: configMap: - description: information about the configMap data - to project + description: configMap information about the configMap + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content @@ -11540,27 +12399,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -11576,13 +12435,13 @@ spec: kind, uid?' type: string optional: - description: Specify whether the ConfigMap - or its keys must be defined + description: optional specify whether the + ConfigMap or its keys must be defined type: boolean type: object downwardAPI: - description: information about the downwardAPI - data to project + description: downwardAPI information about the + downwardAPI data to project properties: items: description: Items is a list of DownwardAPIVolume @@ -11666,11 +12525,11 @@ spec: type: array type: object secret: - description: information about the secret data - to project + description: secret information about the secret + data to project properties: items: - description: If unspecified, each key-value + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content @@ -11687,27 +12546,27 @@ spec: within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used - to set permissions on this file. Must - be an octal value between 0000 and - 0777 or a decimal value between 0 - and 511. YAML accepts both octal and - decimal values, JSON requires decimal - values for mode bits. If not specified, - the volume defaultMode will be used. - This might be in conflict with other - options that affect the file mode, - like fsGroup, and the result can be - other mode bits set.' + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' format: int32 type: integer path: - description: The relative path of the - file to map the key to. May not be - an absolute path. May not contain + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain the path element '..'. May not start with the string '..'. type: string @@ -11723,16 +12582,16 @@ spec: kind, uid?' type: string optional: - description: Specify whether the Secret or - its key must be defined + description: optional field specify whether + the Secret or its key must be defined type: boolean type: object serviceAccountToken: - description: information about the serviceAccountToken - data to project + description: serviceAccountToken is information + about the serviceAccountToken data to project properties: audience: - description: Audience is the intended audience + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise @@ -11740,7 +12599,7 @@ spec: to the identifier of the apiserver. type: string expirationSeconds: - description: ExpirationSeconds is the requested + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively @@ -11753,7 +12612,7 @@ spec: format: int64 type: integer path: - description: Path is the path relative to + description: path is the path relative to the mount point of the file to project the token into. type: string @@ -11764,35 +12623,35 @@ spec: type: array type: object quobyte: - description: Quobyte represents a Quobyte mount on the host + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime properties: group: - description: Group to map volume access to Default is + description: group to map volume access to Default is no group type: string readOnly: - description: ReadOnly here will force the Quobyte volume + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. type: boolean registry: - description: Registry represents a single or multiple + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes type: string tenant: - description: Tenant owning the given Quobyte volume + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin type: string user: - description: User to map volume access to Defaults to + description: user to map volume access to Defaults to serivceaccount user type: string volume: - description: Volume is a string that references an already + description: volume is a string that references an already created Quobyte volume by name. type: string required: @@ -11800,43 +12659,44 @@ spec: - volume type: object rbd: - description: 'RBD represents a Rados Block Device mount + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' properties: fsType: - description: 'Filesystem type of the volume that you - want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' type: string image: - description: 'The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string keyring: - description: 'Keyring is the path to key ring for RBDUser. + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string monitors: - description: 'A collection of Ceph monitors. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' items: type: string type: array pool: - description: 'The rados pool name. Default is rbd. More - info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string readOnly: - description: 'ReadOnly here will force the ReadOnly + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: boolean secretRef: - description: 'SecretRef is name of the authentication + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' properties: @@ -11847,35 +12707,36 @@ spec: type: string type: object user: - description: 'The rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' type: string required: - image - monitors type: object scaleIO: - description: ScaleIO represents a ScaleIO persistent volume + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Default is "xfs". + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". type: string gateway: - description: The host address of the ScaleIO API Gateway. + description: gateway is the host address of the ScaleIO + API Gateway. type: string protectionDomain: - description: The name of the ScaleIO Protection Domain - for the configured storage. + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef references to the secret for + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. properties: @@ -11886,26 +12747,26 @@ spec: type: string type: object sslEnabled: - description: Flag to enable/disable SSL communication + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false type: boolean storageMode: - description: Indicates whether the storage for a volume - should be ThickProvisioned or ThinProvisioned. Default - is ThinProvisioned. + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. type: string storagePool: - description: The ScaleIO Storage Pool associated with - the protection domain. + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. type: string system: - description: The name of the storage system as configured - in ScaleIO. + description: system is the name of the storage system + as configured in ScaleIO. type: string volumeName: - description: The name of a volume already created in - the ScaleIO system that is associated with this volume - source. + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. type: string required: - gateway @@ -11913,57 +12774,58 @@ spec: - system type: object secret: - description: 'Secret represents a secret that should populate + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' properties: defaultMode: - description: 'Optional: mode bits used to set permissions - on created files by default. Must be an octal value - between 0000 and 0777 or a decimal value between 0 - and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults - to 0644. Directories within the path are not affected - by this setting. This might be in conflict with other - options that affect the file mode, like fsGroup, and - the result can be other mode bits set.' + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' format: int32 type: integer items: - description: If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be - relative and may not contain the '..' path or start - with '..'. + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. items: description: Maps a string key to a path within a volume. properties: key: - description: The key to project. + description: key is the key to project. type: string mode: - description: 'Optional: mode bits used to set - permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal - values, JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict with - other options that affect the file mode, like - fsGroup, and the result can be other mode bits - set.' + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' format: int32 type: integer path: - description: The relative path of the file to - map the key to. May not be an absolute path. - May not contain the path element '..'. May not - start with the string '..'. + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. type: string required: - key @@ -11971,30 +12833,30 @@ spec: type: object type: array optional: - description: Specify whether the Secret or its keys - must be defined + description: optional field specify whether the Secret + or its keys must be defined type: boolean secretName: - description: 'Name of the secret in the pod''s namespace - to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' type: string type: object storageos: - description: StorageOS represents a StorageOS volume attached + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string readOnly: - description: Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. type: boolean secretRef: - description: SecretRef specifies the secret to use for + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. properties: @@ -12005,12 +12867,12 @@ spec: type: string type: object volumeName: - description: VolumeName is the human-readable name of + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. type: string volumeNamespace: - description: VolumeNamespace specifies the scope of + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within @@ -12022,25 +12884,26 @@ spec: type: string type: object vsphereVolume: - description: VsphereVolume represents a vSphere volume attached + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine properties: fsType: - description: Filesystem type to mount. Must be a filesystem - type supported by the host operating system. Ex. "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if - unspecified. + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. type: string storagePolicyID: - description: Storage Policy Based Management (SPBM) - profile ID associated with the StoragePolicyName. + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. type: string storagePolicyName: - description: Storage Policy Based Management (SPBM) - profile name. + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. type: string volumePath: - description: Path that identifies vSphere volume vmdk + description: volumePath is the path that identifies + vSphere volume vmdk type: string required: - volumePath @@ -12154,8 +13017,9 @@ spec: for the Argo CD Server component. properties: maxReplicas: - description: upper limit for the number of pods that can - be set by the autoscaler; cannot be smaller than MinReplicas. + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. format: int32 type: integer minReplicas: @@ -12174,23 +13038,26 @@ spec: Scale subresource. properties: apiVersion: - description: API version of the referent + description: apiVersion is the API version of the + referent type: string kind: - description: 'Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds"' + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: - description: 'Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names' + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string required: - kind - name type: object targetCPUUtilizationPercentage: - description: target average CPU utilization (represented - as a percentage of requested CPU) over all the pods; - if not specified the default autoscaling policy will - be used. + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. format: int32 type: integer required: @@ -12354,12 +13221,12 @@ spec: fulfilling the ingress supports SNI. items: description: IngressTLS describes the transport layer - security associated with an Ingress. + security associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included - in the TLS certificate. The values in this list - must match the name/s used in the tlsSecret. Defaults + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. items: @@ -12367,13 +13234,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination - and value of the Host header is used for routing. + and value of the "Host" header is used for routing. type: string type: object type: array @@ -12412,10 +13279,10 @@ spec: the ingress supports SNI. items: description: IngressTLS describes the transport layer security - associated with an Ingress. + associated with an ingress. properties: hosts: - description: Hosts are a list of hosts included in the + description: hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller @@ -12425,13 +13292,13 @@ spec: type: array x-kubernetes-list-type: atomic secretName: - description: SecretName is the name of the secret used + description: secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an IngressRule, the SNI host is used for termination and value of the - Host header is used for routing. + "Host" header is used for routing. type: string type: object type: array @@ -12461,6 +13328,28 @@ spec: description: Resources defines the Compute Resources required by the container for the Argo CD server component. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12481,7 +13370,8 @@ spec: description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object route: @@ -12601,6 +13491,28 @@ spec: description: Resources defines the Compute Resources required by the container for Dex. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12622,7 +13534,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object version: @@ -12640,6 +13552,28 @@ spec: description: Resources defines the Compute Resources required by the container for Keycloak. properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map limits: additionalProperties: anyOf: @@ -12661,7 +13595,7 @@ spec: compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object rootCA: diff --git a/go.mod b/go.mod index db4a3b1cb..c9d9fe51f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/argoproj-labs/argocd-operator -go 1.19 +go 1.20 require ( github.com/argoproj/argo-cd/v2 v2.8.3 @@ -8,9 +8,8 @@ require ( github.com/go-logr/logr v1.2.4 github.com/google/go-cmp v0.5.9 github.com/json-iterator/go v1.1.12 - github.com/keycloak/keycloak-operator v0.0.0-20221116085200-4b9abfb29226 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.27.6 + github.com/onsi/gomega v1.27.10 github.com/openshift/api v3.9.1-0.20190916204813-cdbe64fb0c91+incompatible github.com/openshift/client-go v0.0.0-20200325131901-f7baeb993edb github.com/operator-framework/operator-sdk v0.18.2 @@ -20,72 +19,65 @@ require ( github.com/stretchr/testify v1.8.4 golang.org/x/mod v0.10.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.27.1 - k8s.io/apimachinery v0.27.1 + k8s.io/api v0.28.3 + k8s.io/apimachinery v0.28.3 k8s.io/client-go v12.0.0+incompatible - sigs.k8s.io/controller-runtime v0.14.6 + sigs.k8s.io/controller-runtime v0.16.3 ) require ( - cloud.google.com/go v0.110.1 // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.29 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful v2.16.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/zapr v1.2.3 // indirect + github.com/go-logr/zapr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/spec v0.20.9 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/gnostic v0.5.5 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.43.0 // indirect + github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect + go.uber.org/zap v1.25.0 // indirect golang.org/x/crypto v0.14.0 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.9.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.27.1 // indirect - k8s.io/component-base v0.27.1 // indirect + k8s.io/apiextensions-apiserver v0.28.3 // indirect + k8s.io/component-base v0.28.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect @@ -94,40 +86,36 @@ require ( replace ( github.com/go-check/check => github.com/go-check/check v0.0.0-20180628173108-788fd7840127 - k8s.io/api => k8s.io/api v0.23.1 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.23.1 - k8s.io/apimachinery => k8s.io/apimachinery v0.23.1 - k8s.io/apiserver => k8s.io/apiserver v0.23.1 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.23.1 - k8s.io/client-go => k8s.io/client-go v0.23.1 // Required by prometheus-operator - k8s.io/cloud-provider => k8s.io/cloud-provider v0.23.1 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.23.1 - k8s.io/code-generator => k8s.io/code-generator v0.23.1 - k8s.io/component-base => k8s.io/component-base v0.23.1 - k8s.io/component-helpers => k8s.io/component-helpers v0.23.1 - k8s.io/controller-manager => k8s.io/controller-manager v0.23.1 - k8s.io/cri-api => k8s.io/cri-api v0.23.1 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.23.1 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.23.1 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.23.1 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.23.1 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.23.1 - k8s.io/kubectl => k8s.io/kubectl v0.23.1 - k8s.io/kubelet => k8s.io/kubelet v0.23.1 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.23.1 - k8s.io/metrics => k8s.io/metrics v0.23.1 - k8s.io/mount-utils => k8s.io/mount-utils v0.23.1 + k8s.io/api => k8s.io/api v0.28.3 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.28.3 + k8s.io/apimachinery => k8s.io/apimachinery v0.28.3 + k8s.io/apiserver => k8s.io/apiserver v0.28.3 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.28.3 + k8s.io/client-go => k8s.io/client-go v0.28.3 // Required by prometheus-operator + k8s.io/cloud-provider => k8s.io/cloud-provider v0.28.3 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.28.3 + k8s.io/code-generator => k8s.io/code-generator v0.28.3 + k8s.io/component-base => k8s.io/component-base v0.28.3 + k8s.io/component-helpers => k8s.io/component-helpers v0.28.3 + k8s.io/controller-manager => k8s.io/controller-manager v0.28.3 + k8s.io/cri-api => k8s.io/cri-api v0.28.3 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.28.3 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.28.3 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.28.3 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.28.3 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.28.3 + k8s.io/kubectl => k8s.io/kubectl v0.28.3 + k8s.io/kubelet => k8s.io/kubelet v0.28.3 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.28.3 + k8s.io/metrics => k8s.io/metrics v0.28.3 + k8s.io/mount-utils => k8s.io/mount-utils v0.28.3 k8s.io/node-api => k8s.io/node-api v0.21.1 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.23.1 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.23.1 - k8s.io/sample-controller => k8s.io/sample-controller v0.23.1 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.28.3 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.28.3 + k8s.io/sample-controller => k8s.io/sample-controller v0.28.3 sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 ) -replace k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.23.1 - -replace k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20210323165736-1a6458611d18 - -replace sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.11.0 +replace k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.28.3 replace cloud.google.com/go => cloud.google.com/go v0.99.0 diff --git a/go.sum b/go.sum index 6821bd596..683558fc1 100644 --- a/go.sum +++ b/go.sum @@ -1,26 +1,566 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.3.0/go.mod h1:9IAwXhoyBJ7z9LcAwkj0/7NnPzYaPeZxxVp3zm+5IqA= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= @@ -30,54 +570,36 @@ github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v11.2.8+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3-0.20191028180845-3492b2aff503/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= -github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= -github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= -github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/to v0.3.1-0.20191028180845-3492b2aff503/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/autorest/validation v0.2.1-0.20191028180845-3492b2aff503/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA= @@ -92,8 +614,10 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -101,20 +625,30 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= +github.com/alecthomas/kingpin/v2 v2.3.2/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= 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/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/argoproj/argo-cd/v2 v2.8.3 h1:ybJ7eNoP7/u5Vqncais6WeVRBEGmZmriAIwLEKmWHIA= github.com/argoproj/argo-cd/v2 v2.8.3/go.mod h1:Pkw7r6HKh5k/5Ynl4MvwCG79ktYBk+7PbJxCjXSlT30= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= @@ -126,6 +660,7 @@ github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -140,9 +675,8 @@ github.com/aws/aws-sdk-go v1.31.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -152,13 +686,15 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/brancz/gojsontoyaml v0.0.0-20191212081931-bf2969bbd742/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0= github.com/brancz/kube-rbac-proxy v0.5.0/go.mod h1:cL2VjiIFGS90Cjh5ZZ8+It6tMcBt8rwvuw2J6Mamnl0= @@ -171,16 +707,20 @@ github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -189,14 +729,21 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= @@ -215,12 +762,14 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/prometheus-operator v0.38.1-0.20200424145508-7e176fda06cc/go.mod h1:erio69w1R/aC14D5nfvAXSlE8FT8jt2Hnavc50Dp33A= @@ -229,10 +778,12 @@ github.com/coreos/prometheus-operator v0.40.0/go.mod h1:QOoL5cVI3b1OHgpw8s+pH+Ok github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= @@ -245,10 +796,11 @@ github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5je github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= +github.com/daviddengcn/go-colortext v1.0.0/go.mod h1:zDqEI5NVUop5QPpVJUxE9UO10hRnmkD5G4Pmri9+m4c= github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As= github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= @@ -264,6 +816,7 @@ github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= @@ -288,56 +841,65 @@ github.com/elastic/go-sysinfo v1.0.1/go.mod h1:O/D5m1VpYLwGjCYzEt63g3Z1uO3jXfwyz github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM= -github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= -github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -346,20 +908,28 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= -github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -374,21 +944,21 @@ github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQH github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.17.2/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -404,6 +974,7 @@ github.com/go-openapi/runtime v0.18.0/go.mod h1:uI6pHuxWYTy94zZxgcwJkUWa9wbIlhte github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= @@ -411,8 +982,6 @@ github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcs github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/spec v0.19.7/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= -github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= @@ -421,6 +990,7 @@ github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6 github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= @@ -428,8 +998,6 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= @@ -437,12 +1005,15 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -476,6 +1047,7 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -488,8 +1060,7 @@ github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -507,11 +1078,14 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -529,38 +1103,50 @@ github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= +github.com/golangplus/bytes v1.0.0/go.mod h1:AdRaCFwmc/00ZzELMWb01soso6W1R/++O1XL80yAn+A= +github.com/golangplus/fmt v1.0.0/go.mod h1:zpM0OfbMCjPtd2qkTD/jX2MgiFCqklhSUFyDW44gVQE= +github.com/golangplus/testing v1.0.0/go.mod h1:ZDreixUV3YzhoVraIDyOzHrr76p6NUh6k/pPg/Q3gYA= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= -github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= +github.com/google/cel-go v0.16.1/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-jsonnet v0.16.0/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200417002340-c6e0a841f49a/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -569,15 +1155,27 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gophercloud/gophercloud v0.2.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.6.0/go.mod h1:GICNByuaEBibcjmjvI7QvYJSZEbGkcYwAR7EZK2WMqM= @@ -608,6 +1206,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/grpc-ecosystem/grpc-gateway v1.14.4/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db/go.mod h1:uBKkC2RbarFsvS5jMJHpVhTLvGlGQj9JJwkaePE3FWI= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -660,11 +1260,12 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -679,7 +1280,6 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/integr8ly/grafana-operator/v3 v3.6.0/go.mod h1:pWWg9RerCkkwmTcmaygmfhkjjGilEN30han1yq2MAsA= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jessevdk/go-flags v0.0.0-20180331124232-1c38ed7ad0cc/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -699,6 +1299,7 @@ github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUB github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -713,22 +1314,25 @@ github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/keycloak/keycloak-operator v0.0.0-20221116085200-4b9abfb29226 h1:EYtmTA0WjSXzgFR6g44E0717XL2hqVcJNk4IUZXFvts= -github.com/keycloak/keycloak-operator v0.0.0-20221116085200-4b9abfb29226/go.mod h1:q/tOrPIZPK4etiQevY5sDhhtYW5PkmGybtMEhpj8qyY= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= @@ -741,7 +1345,9 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -762,17 +1368,18 @@ github.com/lightstep/lightstep-tracer-go v0.18.0/go.mod h1:jlF1pusYV4pidLvZ+XD0U github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lovoo/gcloud-opentracing v0.3.0/go.mod h1:ZFqk2y38kMDDikZPAK7ynTTGuyt17nSPdS3K5e+ZTBY= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= @@ -793,19 +1400,19 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= @@ -816,6 +1423,8 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/mikefarah/yaml/v2 v2.4.0/go.mod h1:ahVqZF4n1W4NqwvVnZzC4es67xsW9uR/RRf2RRxieJU= github.com/mikefarah/yq/v2 v2.4.1/go.mod h1:i8SYf1XdgUvY2OFwSqGAtWOOgimD2McJ6iutoxRm4k0= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/minio-go/v7 v7.0.58/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= @@ -827,6 +1436,7 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -837,10 +1447,11 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= @@ -853,6 +1464,7 @@ github.com/mozillazg/go-cos v0.13.0/go.mod h1:Zp6DvvXn0RUOXGJ2chmWt2bLEqRAnJnS3D github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -866,7 +1478,6 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -878,7 +1489,6 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -889,11 +1499,22 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -903,8 +1524,19 @@ github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -918,7 +1550,6 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/openshift/api v0.0.0-20200324160301-f91f52aea878/go.mod h1:7k3+uZYOir97walbYUqApHUA2OPhkQpVJHt0n7GJ6P4= -github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= github.com/openshift/api v3.9.1-0.20190916204813-cdbe64fb0c91+incompatible h1:XKVBXsObu4jv2nzgvjnTZ7eBlM3G9H3mrG8yP4TE61U= github.com/openshift/api v3.9.1-0.20190916204813-cdbe64fb0c91+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc= @@ -953,14 +1584,18 @@ github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChl github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -968,11 +1603,13 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prometheus-community/prom-label-proxy v0.1.1-0.20200616110844-0fbfa11fa8f3/go.mod h1:XdjyZg7LCbCC5FADHtpgNp6kQ0W9beXVGfmcvndMj5Y= github.com/prometheus/alertmanager v0.18.0/go.mod h1:WcxHBl40VSPuOaqWae6l6HpnEOVRIycEJ7i9iYkadEE= github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= @@ -991,6 +1628,10 @@ github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -1000,6 +1641,7 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= @@ -1013,9 +1655,11 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.43.0 h1:iq+BVjvYLei5f27wiuNiB1DN6DYQkp1c8Bx0Vykh5us= -github.com/prometheus/common v0.43.0/go.mod h1:NCvr5cQIh3Y/gy73/RdVtC9r8xxrxwJnB+2lB3BxrFc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1031,6 +1675,9 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/prometheus v0.0.0-20180315085919-58e2a31db8de/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= @@ -1040,6 +1687,7 @@ github.com/prometheus/prometheus v1.8.2-0.20200609102542-5d7e3e970602/go.mod h1: github.com/prometheus/prometheus v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1050,13 +1698,18 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190810000440-0ceca61e4d75/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -1088,6 +1741,7 @@ github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -1102,7 +1756,9 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -1112,10 +1768,9 @@ github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -1125,7 +1780,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1135,6 +1789,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1157,6 +1812,7 @@ github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.23.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= @@ -1177,19 +1833,24 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= go.elastic.co/apm v1.5.0/go.mod h1:OdB9sPtM6Vt7oz3VXt7+KR96i9li74qrxBGHTQygFvk= @@ -1199,15 +1860,16 @@ go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHt go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= +go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k= +go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= +go.etcd.io/etcd/client/v2 v2.305.9/go.mod h1:0NBdNx9wbxtEQLwAQtrDHwx58m02vXpDcgSYI2seohQ= +go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA= +go.etcd.io/etcd/pkg/v3 v3.5.9/go.mod h1:BZl0SAShQFk0IpLWR78T/+pyt8AruMHhTNNX73hkNVY= +go.etcd.io/etcd/raft/v3 v3.5.9/go.mod h1:WnFkqzFdZua4LVlVXQEGhmooLeyS7mqzS4Pf4BCVqXg= +go.etcd.io/etcd/server/v3 v3.5.9/go.mod h1:GgI1fQClQCFIzuVjlvdbMxNbnISt90gdfYyqiAIt65g= +go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -1220,32 +1882,45 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= +go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= +go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0HgMzw5eveuCvFDXY4nSYb4F8t5gdrag= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= +go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= +go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk= +go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.2.0/go.mod h1:YfO3fm683kQpzETxlTGZhGIVmXAhaw3gxeBADbpZtnU= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1259,9 +1934,9 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= +go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1290,11 +1965,11 @@ golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= @@ -1305,14 +1980,29 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1332,11 +2022,19 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1375,7 +2073,6 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1394,13 +2091,31 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= @@ -1412,11 +2127,25 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1430,8 +2159,13 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1460,7 +2194,9 @@ golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1494,61 +2230,88 @@ golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1557,8 +2320,12 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= @@ -1569,13 +2336,15 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190118193359-16909d206f00/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1594,6 +2363,7 @@ golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1604,6 +2374,7 @@ golang.org/x/tools v0.0.0-20190813034749-528a2984e271/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190918214516-5a1a30219888/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1641,29 +2412,46 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200603131246-cc40288be839/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= -gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto= gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= @@ -1682,15 +2470,42 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= @@ -1728,16 +2543,90 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200603110839-e855014d5736/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= +google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1759,13 +2648,31 @@ google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1780,6 +2687,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= @@ -1788,7 +2699,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1803,12 +2713,12 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -1833,7 +2743,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= helm.sh/helm/v3 v3.2.0/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1842,25 +2751,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -k8s.io/api v0.23.1 h1:ncu/qfBfUoClqwkTGbeRqqOqBCRoUAflMuOaOD7J0c8= -k8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo= -k8s.io/apiextensions-apiserver v0.23.1 h1:xxE0q1vLOVZiWORu1KwNRQFsGWtImueOrqSl13sS5EU= -k8s.io/apiextensions-apiserver v0.23.1/go.mod h1:0qz4fPaHHsVhRApbtk3MGXNn2Q9M/cVWWhfHdY2SxiM= -k8s.io/apimachinery v0.23.1 h1:sfBjlDFwj2onG0Ijx5C+SrAoeUscPrmghm7wHP+uXlo= -k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno= -k8s.io/apiserver v0.23.1/go.mod h1:Bqt0gWbeM2NefS8CjWswwd2VNAKN6lUKR85Ft4gippY= +k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= +k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= +k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= +k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= +k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= +k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= +k8s.io/apiserver v0.28.3/go.mod h1:YIpM+9wngNAv8Ctt0rHG4vQuX/I5rvkEMtZtsxW2rNM= k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e/go.mod h1:QEXezc9uKPT91dwqhSJq3GNI3B1HxFRQHiku9kmrsSA= -k8s.io/cli-runtime v0.23.1/go.mod h1:r9r8H/qfXo9w+69vwUL7LokKlLRKW5D6A8vUKCx+YL0= -k8s.io/client-go v0.23.1 h1:Ma4Fhf/p07Nmj9yAB1H7UwbFHEBrSPg8lviR24U2GiQ= -k8s.io/client-go v0.23.1/go.mod h1:6QSI8fEuqD4zgFK0xbdwfB/PthBsIxCJMa3s17WlcO0= -k8s.io/code-generator v0.23.1/go.mod h1:V7yn6VNTCWW8GqodYCESVo95fuiEg713S8B7WacWZDA= -k8s.io/component-base v0.23.1 h1:j/BqdZUWeWKCy2v/jcgnOJAzpRYWSbGcjGVYICko8Uc= -k8s.io/component-base v0.23.1/go.mod h1:6llmap8QtJIXGDd4uIWJhAq0Op8AtQo6bDW2RrNMTeo= -k8s.io/component-helpers v0.23.1/go.mod h1:ZK24U+2oXnBPcas2KolLigVVN9g5zOzaHLkHiQMFGr0= +k8s.io/cli-runtime v0.28.3/go.mod h1:jeX37ZPjIcENVuXDDTskG3+FnVuZms5D9omDXS/2Jjc= +k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= +k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= +k8s.io/code-generator v0.28.3/go.mod h1:A2EAHTRYvCvBrb/MM2zZBNipeCk3f8NtpdNIKawC43M= +k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= +k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= +k8s.io/component-helpers v0.28.3/go.mod h1:oJR7I9ist5UAQ3y/CTdbw6CXxdMZ1Lw2Ua/EZEwnVLs= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= @@ -1868,41 +2780,83 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20210323165736-1a6458611d18 h1:BWMcoT2cx+iaBhcemnBAA0G58WbBWgfh1V05r/uSPJs= -k8s.io/kube-openapi v0.0.0-20210323165736-1a6458611d18/go.mod h1:UDkTDGblU9FBGrWsHAJ8G3ukmPKbCiJL1gCuA1DFd4I= +k8s.io/kms v0.28.3/go.mod h1:kSMjU2tg7vjqqoWVVCcmPmNZ/CofPsoTbSxAipCvZuE= +k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= +k8s.io/kube-openapi v0.0.0-20230109183929-3758b55a6596/go.mod h1:/BYxry62FuDzmI+i9B+X2pqfySRmSOW2ARmj5Zbqhj0= +k8s.io/kube-openapi v0.0.0-20230531092745-9b4dcd38a4bf/go.mod h1:l8HTwL5fqnlns4jOveW1L75eo7R9KFHxiE0bsPGy428= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E= -k8s.io/kubectl v0.23.1/go.mod h1:Ui7dJKdUludF8yWAOSN7JZEkOuYixX5yF6E6NjoukKE= +k8s.io/kubectl v0.28.3/go.mod h1:RDAudrth/2wQ3Sg46fbKKl4/g+XImzvbsSRZdP2RiyE= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/metrics v0.23.1/go.mod h1:qXvsM1KANrc+ZZeFwj6Phvf0NLiC+d3RwcsLcdGc+xs= +k8s.io/metrics v0.28.3/go.mod h1:OZZ23AHFojPzU6r3xoHGRUcV3I9pauLua+07sAUbwLc= k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200414100711-2df71ebbae66/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I= -sigs.k8s.io/controller-runtime v0.11.0 h1:DqO+c8mywcZLFJWILq4iktoECTyn30Bkj0CwgqMpZWQ= -sigs.k8s.io/controller-runtime v0.11.0/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2/go.mod h1:+qG7ISXqCDVVcyO8hLn12AKVYYUjM7ftlqsqmrhMZE0= +sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= +sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= +sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= sigs.k8s.io/kubebuilder v1.0.9-0.20200513134826-f07a0146a40b/go.mod h1:FGPx0hvP73+bapzWoy5ePuhAJYgJjrFbPxgvWyortM0= -sigs.k8s.io/kustomize/api v0.10.1/go.mod h1:2FigT1QN6xKdcnGS2Ppp1uIWrtWN28Ms8A3OZUZhwr8= -sigs.k8s.io/kustomize/cmd/config v0.10.2/go.mod h1:K2aW7nXJ0AaT+VA/eO0/dzFLxmpFcTzudmAgDwPY1HQ= -sigs.k8s.io/kustomize/kustomize/v4 v4.4.1/go.mod h1:qOKJMMz2mBP+vcS7vK+mNz4HBLjaQSWRY22EF6Tb7Io= -sigs.k8s.io/kustomize/kyaml v0.13.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/kustomize/api v0.13.4/go.mod h1:Bkaavz5RKK6ZzP0zgPrB7QbpbBJKiHuD3BB0KujY7Ls= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= +sigs.k8s.io/kustomize/cmd/config v0.11.2/go.mod h1:PCpHxyu10daTnbMfn3xhH1vppn7L8jsS3qpRKXb7Lkc= +sigs.k8s.io/kustomize/kustomize/v5 v5.0.4-0.20230601165947-6ce0bf390ce3/go.mod h1:/d88dHCvoy7d0AKFT0yytezSGZKjsZBVs9YTkBHSGFk= +sigs.k8s.io/kustomize/kyaml v0.14.2/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/main.go b/main.go index 1cfecade7..c47ac8e06 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "crypto/tls" "flag" "fmt" "os" @@ -34,11 +35,14 @@ import ( sdkVersion "github.com/operator-framework/operator-sdk/version" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/webhook" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd" "github.com/argoproj-labs/argocd-operator/controllers/argocdexport" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. _ "k8s.io/client-go/plugin/pkg/client/auth" @@ -82,18 +86,43 @@ func main() { var enableLeaderElection bool var probeAddr string var labelSelectorFlag string + + var secureMetrics = false + var enableHTTP2 = false + flag.StringVar(&metricsAddr, "metrics-bind-address", fmt.Sprintf(":%d", common.OperatorMetricsPort), "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.StringVar(&labelSelectorFlag, "label-selector", env.StringFromEnv(common.ArgoCDLabelSelectorKey, common.ArgoCDDefaultLabelSelector), "The label selector is used to map to a subset of ArgoCD instances to reconcile") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&enableHTTP2, "enable-http2", enableHTTP2, "If HTTP/2 should be enabled for the metrics and webhook servers.") + flag.BoolVar(&secureMetrics, "metrics-secure", secureMetrics, "If the metrics endpoint should be served securely.") + opts := zap.Options{ Development: true, } opts.BindFlags(flag.CommandLine) flag.Parse() + disableHTTP2 := func(c *tls.Config) { + if enableHTTP2 { + return + } + c.NextProtos = []string{"http/1.1"} + } + webhookServerOptions := webhook.Options{ + TLSOpts: []func(config *tls.Config){disableHTTP2}, + Port: 9443, + } + webhookServer := webhook.NewServer(webhookServerOptions) + + metricsServerOptions := metricsserver.Options{ + SecureServing: secureMetrics, + BindAddress: metricsAddr, + TLSOpts: []func(*tls.Config){disableHTTP2}, + } + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) printVersion() @@ -118,22 +147,18 @@ func main() { // Set default manager options options := manager.Options{ - Namespace: namespace, + Metrics: metricsServerOptions, + WebhookServer: webhookServer, Scheme: scheme, - MetricsBindAddress: metricsAddr, - Port: 9443, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "b674928d.argoproj.io", } - // Add support for MultiNamespace set in WATCH_NAMESPACE (e.g ns1,ns2) - // Note that this is not intended to be used for excluding namespaces, this is better done via a Predicate - // Also note that you may face performance issues when using this with a high number of namespaces. - // More Info: https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/cache#MultiNamespacedCacheBuilder - if strings.Contains(namespace, ",") { - options.Namespace = "" - options.NewCache = cache.MultiNamespacedCacheBuilder(strings.Split(namespace, ",")) + if watchedNsCache := getDefaultWatchedNamespacesCacheOptions(); watchedNsCache != nil { + options.Cache = cache.Options{ + DefaultNamespaces: watchedNsCache, + } } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) @@ -235,3 +260,25 @@ func main() { os.Exit(1) } } + +func getDefaultWatchedNamespacesCacheOptions() map[string]cache.Config { + watchedNamespaces, err := k8sutil.GetWatchNamespace() + if err != nil { + setupLog.Error(err, "Failed to get watch namespace, defaulting to all namespace mode") + return nil + } + + if watchedNamespaces == "" { + return nil + } + + watchedNsList := strings.Split(watchedNamespaces, ",") + setupLog.Info(fmt.Sprintf("Watching namespaces: %v", watchedNsList)) + + defaultNamespacesCacheConfig := map[string]cache.Config{} + for _, ns := range watchedNsList { + defaultNamespacesCacheConfig[ns] = cache.Config{} + } + + return defaultNamespacesCacheConfig +} diff --git a/tests/auxiliary/smtplistener/internal/processor/filewriter.go b/tests/auxiliary/smtplistener/internal/processor/filewriter.go index 8a0d3041f..be47ef0c6 100644 --- a/tests/auxiliary/smtplistener/internal/processor/filewriter.go +++ b/tests/auxiliary/smtplistener/internal/processor/filewriter.go @@ -2,7 +2,7 @@ package processor import ( "fmt" - "io/ioutil" + "os" "github.com/flashmob/go-guerrilla/backends" "github.com/flashmob/go-guerrilla/mail" @@ -26,7 +26,7 @@ var FileWriter = func() backends.Decorator { stringer = e data := []byte(stringer.String()) key := fmt.Sprintf("%s%s", "/tmp/", e.QueuedId) - err := ioutil.WriteFile(key, data, 0666) + err := os.WriteFile(key, data, 0666) fmt.Println(err) return p.Process(e, task) } else { From fb2706631987a958db9d10cb5077b4efcced85d9 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Thu, 26 Oct 2023 19:33:34 +0530 Subject: [PATCH 33/94] Add gcp cherry-pick bot config (#1023) Signed-off-by: Siddhesh Ghadi --- .github/cherry-pick-bot.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/cherry-pick-bot.yml diff --git a/.github/cherry-pick-bot.yml b/.github/cherry-pick-bot.yml new file mode 100644 index 000000000..1f62315d7 --- /dev/null +++ b/.github/cherry-pick-bot.yml @@ -0,0 +1,2 @@ +enabled: true +preservePullRequestTitle: true From cd9e704aed3978d2e4fc2b3cb3b267709ea3d6f9 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Thu, 26 Oct 2023 16:13:57 -0400 Subject: [PATCH 34/94] Updated logic to decide if use TLS for redis Signed-off-by: Yi Cai --- common/values.go | 2 ++ controllers/argocd/reposerver/deployment.go | 16 +++++----------- controllers/argocd/reposerver/deployment_test.go | 4 ++-- controllers/argocd/reposerver/reposerver.go | 2 ++ controllers/argocd/reposerver/reposerver_test.go | 1 + controllers/argocd/reposerver/service.go | 4 +--- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/common/values.go b/common/values.go index 4937f211e..8b3951d09 100644 --- a/common/values.go +++ b/common/values.go @@ -62,6 +62,8 @@ const ( CapabilityDropAll = "ALL" + OpenShift = "openshift" + VolumeMountPathTLS = "/app/config/tls" VolumeMountPathRepoServerTLS = "/app/config/reposerver/tls" WorkingDirApp = "/app" diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 02588b392..e8416a15c 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -24,16 +24,10 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { rsr.Logger.Info("reconciling deployment") - useTLSForRedis, err := argocdcommon.ShouldUseTLS(rsr.Client, rsr.Instance.Namespace) - if err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to determine if TLS should be used for Redis") - return err - } - - desiredDeployment := rsr.getDesiredDeployment(useTLSForRedis) + desiredDeployment := rsr.getDesiredDeployment() deploymentRequest := rsr.getDeploymentRequest(*desiredDeployment) - desiredDeployment, err = workloads.RequestDeployment(deploymentRequest) + desiredDeployment, err := workloads.RequestDeployment(deploymentRequest) if err != nil { rsr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err @@ -127,7 +121,7 @@ func (rsr *RepoServerReconciler) deleteDeployment(name, namespace string) error return nil } -func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *appsv1.Deployment { +func (rsr *RepoServerReconciler) getDesiredDeployment() *appsv1.Deployment { desiredDeployment := &appsv1.Deployment{} automountToken := false @@ -143,7 +137,7 @@ func (rsr *RepoServerReconciler) getDesiredDeployment(useTLSForRedis bool) *apps podSpec := corev1.PodSpec{ Volumes: rsr.getRepoServerPodVolumes(), InitContainers: rsr.getRepoSeverInitContainers(), - Containers: rsr.getRepoServerContainers(useTLSForRedis), + Containers: rsr.getRepoServerContainers(), SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: util.BoolPtr(true), }, @@ -223,7 +217,7 @@ func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container return initContainers } -func (rsr *RepoServerReconciler) getRepoServerContainers(useTLSForRedis bool) []corev1.Container { +func (rsr *RepoServerReconciler) getRepoServerContainers() []corev1.Container { repoServerEnv := rsr.Instance.Spec.Repo.Env repoServerEnv = util.EnvMerge(repoServerEnv, util.ProxyEnvVars(), false) diff --git a/controllers/argocd/reposerver/deployment_test.go b/controllers/argocd/reposerver/deployment_test.go index 5ed5db07c..1588244ae 100644 --- a/controllers/argocd/reposerver/deployment_test.go +++ b/controllers/argocd/reposerver/deployment_test.go @@ -34,7 +34,7 @@ func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { { name: "update a deployment when doesn't use TLS for Redis", setupClient: func(useTLSForRedis bool) *RepoServerReconciler { - existingDeployment := rsr.getDesiredDeployment(useTLSForRedis) + existingDeployment := rsr.getDesiredDeployment() outdatedDeployment := existingDeployment outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" return makeTestRepoServerReconciler(t, outdatedDeployment, ns) @@ -45,7 +45,7 @@ func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { { name: "update a deployment when use TLS for Redis", setupClient: func(useTLSForRedis bool) *RepoServerReconciler { - existingDeployment := rsr.getDesiredDeployment(useTLSForRedis) + existingDeployment := rsr.getDesiredDeployment() outdatedDeployment := existingDeployment outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" return makeTestRepoServerReconciler(t, outdatedDeployment, ns) diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 544e4b3b6..0863b234e 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -31,12 +31,14 @@ type RepoServerReconciler struct { var ( resourceName string resourceLabels map[string]string + useTLSForRedis bool ) func (rsr *RepoServerReconciler) Reconcile() error { rsr.Logger = ctrl.Log.WithName(common.RepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) resourceName = util.GenerateResourceName(rsr.Instance.Name, common.RepoServerControllerComponent) resourceLabels = common.DefaultLabels(resourceName, rsr.Instance.Name, common.RepoServerControllerComponent) + useTLSForRedis = rsr.Instance.Spec.Repo.WantsAutoTLS() if err := rsr.reconcileService(); err != nil { rsr.Logger.Info("reconciling repo server service") diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index 6d1463790..68f02a896 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -34,6 +34,7 @@ func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoSer Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.Repo = argoproj.ArgoCDRepoSpec{ ServiceAccount: testServiceAccount, + AutoTLS: common.OpenShift, } a.ObjectMeta = metav1.ObjectMeta{ Name: argocdcommon.TestArgoCDName, diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index e6b9df1d0..9128b3f59 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -58,8 +58,6 @@ func (rsr *RepoServerReconciler) reconcileService() error { rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desiredService.Name, "namespace", desiredService.Namespace) } - // networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Spec.Repo.WantsAutoTLS(), rsr.Logger) - if err = networking.CreateService(desiredService, rsr.Client); err != nil { rsr.Logger.Error(err, "reconcileService: failed to create service", "name", desiredService.Name, "namespace", desiredService.Namespace) return err @@ -68,7 +66,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { return nil } - if networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Spec.Repo.WantsAutoTLS(), rsr.Logger) { + if networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, useTLSForRedis, rsr.Logger) { if err = networking.UpdateService(existingService, rsr.Client); err != nil { rsr.Logger.Error(err, "reconcileService: failed to update service", "name", existingService.Name, "namespace", existingService.Namespace) return err From 962f30f20d134e68929182281de2349f51eb149a Mon Sep 17 00:00:00 2001 From: Cheng Fang Date: Fri, 27 Oct 2023 02:02:38 -0400 Subject: [PATCH 35/94] Add .github/dependabot.yml to enable auto dependency version updates (#1025) --- .github/dependabot.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..f371d4275 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,39 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "docker" + directory: "/build/" + schedule: + interval: "daily" + + - package-ecosystem: "docker" + directory: "/build/util/" + schedule: + interval: "daily" + + - package-ecosystem: "docker" + directory: "/deploy/registry/" + schedule: + interval: "daily" + + - package-ecosystem: "docker" + directory: "/tests/auxiliary/smtplistener/" + schedule: + interval: "daily" From 000c4a7257a8feaf9f244276ad35c26a2a0a4720 Mon Sep 17 00:00:00 2001 From: Robert Deusser <5935071+rdeusser@users.noreply.github.com> Date: Mon, 30 Oct 2023 05:30:46 -0400 Subject: [PATCH 36/94] feat(dex): add optional env field (#1005) * feat(dex): add optional env field Signed-off-by: Robert Deusser * fix: remove non-default configuration Signed-off-by: Robert Deusser * fix: v1alpha1 is deprecated Signed-off-by: Robert Deusser * fix: convert dex spec between api versions Signed-off-by: Robert Deusser * fix: ensure there is no diff in the bundle Signed-off-by: Robert Deusser --------- Signed-off-by: Robert Deusser --- api/v1alpha1/argocd_conversion.go | 37 ++- api/v1beta1/argocd_types.go | 3 + api/v1beta1/zz_generated.deepcopy.go | 7 + bundle/manifests/argoproj.io_argocds.yaml | 115 +++++++ config/crd/bases/argoproj.io_argocds.yaml | 115 +++++++ controllers/argocd/dex.go | 11 +- controllers/argocd/dex_test.go | 302 +++++++++++++----- .../0.8.0/argoproj.io_argocds.yaml | 115 +++++++ docs/reference/argocd.md | 33 +- docs/usage/dex.md | 48 ++- .../1-015_validate_sso_status/06-assert.yaml | 36 +++ .../06-dex-spec-sso-env.yaml | 15 + 12 files changed, 719 insertions(+), 118 deletions(-) create mode 100644 tests/k8s/1-015_validate_sso_status/06-assert.yaml create mode 100644 tests/k8s/1-015_validate_sso_status/06-dex-spec-sso-env.yaml diff --git a/api/v1alpha1/argocd_conversion.go b/api/v1alpha1/argocd_conversion.go index 64270ff43..591924240 100644 --- a/api/v1alpha1/argocd_conversion.go +++ b/api/v1alpha1/argocd_conversion.go @@ -45,7 +45,7 @@ func (src *ArgoCD) ConvertTo(dstRaw conversion.Hub) error { sso = &v1beta1.ArgoCDSSOSpec{} } sso.Provider = v1beta1.SSOProviderTypeDex - sso.Dex = (*v1beta1.ArgoCDDexSpec)(src.Spec.Dex) + sso.Dex = ConvertAlphaToBetaDex(src.Spec.Dex) } dst.Spec.SSO = sso @@ -244,13 +244,29 @@ func ConvertAlphaToBetaSSO(src *ArgoCDSSOSpec) *v1beta1.ArgoCDSSOSpec { if src != nil { dst = &v1beta1.ArgoCDSSOSpec{ Provider: v1beta1.SSOProviderType(src.Provider), - Dex: (*v1beta1.ArgoCDDexSpec)(src.Dex), + Dex: ConvertAlphaToBetaDex(src.Dex), Keycloak: (*v1beta1.ArgoCDKeycloakSpec)(src.Keycloak), } } return dst } +func ConvertAlphaToBetaDex(src *ArgoCDDexSpec) *v1beta1.ArgoCDDexSpec { + var dst *v1beta1.ArgoCDDexSpec + if src != nil { + dst = &v1beta1.ArgoCDDexSpec{ + Config: src.Config, + Groups: src.Groups, + Image: src.Image, + OpenShiftOAuth: src.OpenShiftOAuth, + Resources: src.Resources, + Version: src.Version, + Env: nil, + } + } + return dst +} + func ConvertAlphaToBetaHA(src *ArgoCDHASpec) *v1beta1.ArgoCDHASpec { var dst *v1beta1.ArgoCDHASpec if src != nil { @@ -448,13 +464,28 @@ func ConvertBetaToAlphaSSO(src *v1beta1.ArgoCDSSOSpec) *ArgoCDSSOSpec { if src != nil { dst = &ArgoCDSSOSpec{ Provider: SSOProviderType(src.Provider), - Dex: (*ArgoCDDexSpec)(src.Dex), + Dex: ConvertBetaToAlphaDex(src.Dex), Keycloak: (*ArgoCDKeycloakSpec)(src.Keycloak), } } return dst } +func ConvertBetaToAlphaDex(src *v1beta1.ArgoCDDexSpec) *ArgoCDDexSpec { + var dst *ArgoCDDexSpec + if src != nil { + dst = &ArgoCDDexSpec{ + Config: src.Config, + Groups: src.Groups, + Image: src.Image, + OpenShiftOAuth: src.OpenShiftOAuth, + Resources: src.Resources, + Version: src.Version, + } + } + return dst +} + func ConvertBetaToAlphaHA(src *v1beta1.ArgoCDHASpec) *ArgoCDHASpec { var dst *ArgoCDHASpec if src != nil { diff --git a/api/v1beta1/argocd_types.go b/api/v1beta1/argocd_types.go index 5c55851f4..7a401eba4 100644 --- a/api/v1beta1/argocd_types.go +++ b/api/v1beta1/argocd_types.go @@ -203,6 +203,9 @@ type ArgoCDDexSpec struct { // Version is the Dex container image tag. //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex","urn:alm:descriptor:com.tectonic.ui:text"} Version string `json:"version,omitempty"` + + // Env lets you specify environment variables for Dex. + Env []corev1.EnvVar `json:"env,omitempty"` } // ArgoCDGrafanaSpec defines the desired state for the Grafana component. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 864d81bca..cf6ca277c 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -202,6 +202,13 @@ func (in *ArgoCDDexSpec) DeepCopyInto(out *ArgoCDDexSpec) { *out = new(v1.ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDDexSpec. diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index e8ba59f6c..82cd8b2ad 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -13474,6 +13474,121 @@ spec: config: description: Config is the dex connector configuration. type: string + env: + description: Env lets you specify environment variables for + Dex. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array groups: description: Optional list of required groups a user must be a member of diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 51f836e37..98a1c8fdc 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -13465,6 +13465,121 @@ spec: config: description: Config is the dex connector configuration. type: string + env: + description: Env lets you specify environment variables for + Dex. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array groups: description: Optional list of required groups a user must be a member of diff --git a/controllers/argocd/dex.go b/controllers/argocd/dex.go index 916b84aa3..fdc7704c0 100644 --- a/controllers/argocd/dex.go +++ b/controllers/argocd/dex.go @@ -133,7 +133,6 @@ func (r *ReconcileArgoCD) reconcileDexConfiguration(cm *corev1.ConfigMap, cr *ar // getOpenShiftDexConfig will return the configuration for the Dex server running on OpenShift. func (r *ReconcileArgoCD) getOpenShiftDexConfig(cr *argoproj.ArgoCD) (string, error) { - groups := []string{} // Allow override of groups from CR @@ -167,7 +166,6 @@ func (r *ReconcileArgoCD) getOpenShiftDexConfig(cr *argoproj.ArgoCD) (string, er // reconcileDexServiceAccount will ensure that the Dex ServiceAccount is configured properly for OpenShift OAuth. func (r *ReconcileArgoCD) reconcileDexServiceAccount(cr *argoproj.ArgoCD) error { - // if openShiftOAuth set to false in `.spec.sso.dex`, no need to configure it if cr.Spec.SSO == nil || cr.Spec.SSO.Dex == nil || !cr.Spec.SSO.Dex.OpenShiftOAuth { return nil // OpenShift OAuth not enabled, move along... @@ -207,6 +205,11 @@ func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoproj.ArgoCD) error { AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) + dexEnv := proxyEnvVars() + if cr.Spec.SSO != nil && cr.Spec.SSO.Dex != nil { + dexEnv = append(dexEnv, cr.Spec.SSO.Dex.Env...) + } + deploy.Spec.Template.Spec.Containers = []corev1.Container{{ Command: []string{ "/shared/argocd-dex", @@ -214,7 +217,7 @@ func (r *ReconcileArgoCD) reconcileDexDeployment(cr *argoproj.ArgoCD) error { }, Image: getDexContainerImage(cr), Name: "dex", - Env: proxyEnvVars(), + Env: dexEnv, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ @@ -397,7 +400,6 @@ func (r *ReconcileArgoCD) reconcileDexService(cr *argoproj.ArgoCD) error { // reconcileDexResources consolidates all dex resources reconciliation calls. It serves as the single place to trigger both creation // and deletion of dex resources based on the specified configuration of dex func (r *ReconcileArgoCD) reconcileDexResources(cr *argoproj.ArgoCD) error { - if _, err := r.reconcileRole(common.ArgoCDDexServerComponent, policyRuleForDexServer(), cr); err != nil { log.Error(err, "error reconciling dex role") } @@ -441,7 +443,6 @@ func (r *ReconcileArgoCD) reconcileDexResources(cr *argoproj.ArgoCD) error { // Deployment and RoleBinding must be deleted before the role and sa. deleteDexResources will only be called during // delete events, so we don't need to worry about duplicate, recurring reconciliation calls func (r *ReconcileArgoCD) deleteDexResources(cr *argoproj.ArgoCD) error { - sa := &corev1.ServiceAccount{} role := &rbacv1.Role{} diff --git a/controllers/argocd/dex_test.go b/controllers/argocd/dex_test.go index 7c7acf74c..3f0ca40a2 100644 --- a/controllers/argocd/dex_test.go +++ b/controllers/argocd/dex_test.go @@ -332,7 +332,8 @@ func TestReconcileArgoCD_reconcileDexDeployment(t *testing.T) { RunAsNonRoot: boolPtr(true), }, VolumeMounts: []corev1.VolumeMount{ - {Name: "static-files", MountPath: "/shared"}}, + {Name: "static-files", MountPath: "/shared"}, + }, }, }, ServiceAccountName: "argocd-argocd-dex-server", @@ -344,92 +345,6 @@ func TestReconcileArgoCD_reconcileDexDeployment(t *testing.T) { func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) { logf.SetLogger(ZapLogger(true)) - desiredPodSpec := corev1.PodSpec{ - Volumes: []corev1.Volume{ - { - Name: "static-files", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - }, - InitContainers: []corev1.Container{ - { - Name: "copyutil", - Image: "justatest:latest", - Command: []string{ - "cp", - "-n", - "/usr/local/bin/argocd", - "/shared/argocd-dex", - }, - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - RunAsNonRoot: boolPtr(true), - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "static-files", - MountPath: "/shared", - }, - }, - ImagePullPolicy: corev1.PullAlways, - }, - }, - Containers: []corev1.Container{ - { - Name: "dex", - Image: "testdex:v0.0.1", - Command: []string{ - "/shared/argocd-dex", - "rundex", - }, - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/healthz/live", - Port: intstr.FromInt(5558), - }, - }, - InitialDelaySeconds: 60, - PeriodSeconds: 30, - }, - Ports: []corev1.ContainerPort{ - { - Name: "http", - ContainerPort: 5556, - }, - { - Name: "grpc", - ContainerPort: 5557, - }, - { - Name: "metrics", - ContainerPort: 5558, - }, - }, - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - RunAsNonRoot: boolPtr(true), - }, - VolumeMounts: []corev1.VolumeMount{ - {Name: "static-files", MountPath: "/shared"}}, - }, - }, - ServiceAccountName: "argocd-argocd-dex-server", - NodeSelector: common.DefaultNodeSelector(), - } - tests := []struct { name string setEnvFunc func(*testing.T, string) @@ -459,7 +374,218 @@ func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) { }, } }), - wantPodSpec: desiredPodSpec, + wantPodSpec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "static-files", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }, + InitContainers: []corev1.Container{ + { + Name: "copyutil", + Image: "justatest:latest", + Command: []string{ + "cp", + "-n", + "/usr/local/bin/argocd", + "/shared/argocd-dex", + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "static-files", + MountPath: "/shared", + }, + }, + ImagePullPolicy: corev1.PullAlways, + }, + }, + Containers: []corev1.Container{ + { + Name: "dex", + Image: "testdex:v0.0.1", + Command: []string{ + "/shared/argocd-dex", + "rundex", + }, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/healthz/live", + Port: intstr.FromInt(5558), + }, + }, + InitialDelaySeconds: 60, + PeriodSeconds: 30, + }, + Ports: []corev1.ContainerPort{ + { + Name: "http", + ContainerPort: 5556, + }, + { + Name: "grpc", + ContainerPort: 5557, + }, + { + Name: "metrics", + ContainerPort: 5558, + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + {Name: "static-files", MountPath: "/shared"}, + }, + }, + }, + ServiceAccountName: "argocd-argocd-dex-server", + NodeSelector: common.DefaultNodeSelector(), + }, + }, + { + name: "update dex deployment - .spec.sso.dex.env", + setEnvFunc: nil, + updateCrFunc: func(cr *argoproj.ArgoCD) { + cr.Spec.SSO.Dex.Env = []corev1.EnvVar{ + { + Name: "ARGO_WORKFLOWS_SSO_CLIENT_SECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "argo-workflows-sso", + }, + Key: "client-secret", + }, + }, + }, + } + }, + argoCD: makeTestArgoCD(func(cr *argoproj.ArgoCD) { + cr.Spec.SSO = &argoproj.ArgoCDSSOSpec{ + Provider: argoproj.SSOProviderTypeDex, + Dex: &argoproj.ArgoCDDexSpec{ + OpenShiftOAuth: true, + }, + } + }), + wantPodSpec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "static-files", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }, + InitContainers: []corev1.Container{ + { + Name: "copyutil", + Image: "quay.io/argoproj/argocd@sha256:d40da8f5747415eb7f9b5c2d9b645aecd423888cad9b36e4f986bff8ecf0a786", + Command: []string{ + "cp", + "-n", + "/usr/local/bin/argocd", + "/shared/argocd-dex", + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "static-files", + MountPath: "/shared", + }, + }, + ImagePullPolicy: corev1.PullAlways, + }, + }, + Containers: []corev1.Container{ + { + Name: "dex", + Image: "ghcr.io/dexidp/dex@sha256:d5f887574312f606c61e7e188cfb11ddb33ff3bf4bd9f06e6b1458efca75f604", + Command: []string{ + "/shared/argocd-dex", + "rundex", + }, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/healthz/live", + Port: intstr.FromInt(5558), + }, + }, + InitialDelaySeconds: 60, + PeriodSeconds: 30, + }, + Ports: []corev1.ContainerPort{ + { + Name: "http", + ContainerPort: 5556, + }, + { + Name: "grpc", + ContainerPort: 5557, + }, + { + Name: "metrics", + ContainerPort: 5558, + }, + }, + Env: []corev1.EnvVar{ + { + Name: "ARGO_WORKFLOWS_SSO_CLIENT_SECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "argo-workflows-sso", + }, + Key: "client-secret", + }, + }, + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + {Name: "static-files", MountPath: "/shared"}, + }, + }, + }, + ServiceAccountName: "argocd-argocd-dex-server", + NodeSelector: common.DefaultNodeSelector(), + }, }, } diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index e8ba59f6c..82cd8b2ad 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -13474,6 +13474,121 @@ spec: config: description: Config is the dex connector configuration. type: string + env: + description: Env lets you specify environment variables for + Dex. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array groups: description: Optional list of required groups a user must be a member of diff --git a/docs/reference/argocd.md b/docs/reference/argocd.md index 4bb5f1b74..0c7e8d2f1 100644 --- a/docs/reference/argocd.md +++ b/docs/reference/argocd.md @@ -104,7 +104,7 @@ spec: ### Add Command Arguments to ApplicationSets Controller -Below example shows how a user can add command arguments to the ApplicationSet controller. +Below example shows how a user can add command arguments to the ApplicationSet controller. ``` yaml apiVersion: argoproj.io/v1alpha1 @@ -137,7 +137,6 @@ spec: SCMRootCAConfigMap: example-gitlab-scm-tls-cert ``` - ## Config Management Plugins Configuration to add a config management plugin. This property maps directly to the `configManagementPlugins` field in the `argocd-cm` ConfigMap. @@ -200,7 +199,7 @@ spec: resources: {} ``` -The following example shows how to set command line parameters using the env variable +The following example shows how to set command line parameters using the env variable ``` yaml apiVersion: argoproj.io/v1alpha1 @@ -213,7 +212,7 @@ spec: controller: env: - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS - value: '120' + value: '120' ``` The following example shows how to set multiple replicas of Argo CD Application Controller. This example will scale up/down the Argo CD Application Controller based on the parameter clustersPerShard. The number of replicas will be set between minShards and maxShards. @@ -237,7 +236,6 @@ spec: !!! note In case the number of replicas required is less than the minShards the number of replicas will be set as minShards. Similarly, if the required number of replicas exceeds maxShards, the replica count will be set as maxShards. - The following example shows how to enable dynamic scaling of the ArgoCD Application Controller component. ```yaml @@ -757,10 +755,10 @@ metadata: labels: example: nodeplacement-example spec: - nodePlacement: - nodeSelector: + nodePlacement: + nodeSelector: key1: value1 - tolerations: + tolerations: - key: key1 operator: Equal value: value1 @@ -768,7 +766,7 @@ spec: - key: key1 operator: Equal value: value1 - effect: NoExecute + effect: NoExecute ``` ## Prometheus Options @@ -965,7 +963,7 @@ spec: Resource behavior can be customized using subkeys (`resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions`). Each of the subkeys maps directly to their own field in the `argocd-cm`. `resourceHealthChecks` will map to `resource.customizations.health`, `resourceIgnoreDifferences` to `resource.customizations.ignoreDifferences`, and `resourceActions` to `resource.customizations.actions`. -!!! note +!!! note `.spec.resourceCustomizations` field is no longer in support from Argo CD Operator v0.8.0 onward. Consider using `resourceHealthChecks`, `resourceIgnoreDifferences`, and `resourceActions` instead. ### Resource Customizations (with subkeys) @@ -1058,7 +1056,7 @@ spec: return obj ``` -After applying these changes your `argocd-cm` Configmap should contain the following fields: +After applying these changes your `argocd-cm` Configmap should contain the following fields: ``` resource.customizations.ignoreDifferences.apps_Deployment: | @@ -1148,7 +1146,7 @@ spec: - /spec/replicas ``` -After applying these changes your `argocd-cm` Configmap should contain the following fields: +After applying these changes your `argocd-cm` Configmap should contain the following fields: ``` resource.customizations.ignoreDifferences.admissionregistration.k8s.io_MutatingWebhookConfiguration: | @@ -1227,7 +1225,7 @@ spec: ## Resource Tracking Method -You can configure which +You can configure which [resource tracking method](https://argo-cd.readthedocs.io/en/stable/user-guide/resource_tracking/#choosing-a-tracking-method) Argo CD should use to keep track of the resources it manages. @@ -1286,7 +1284,7 @@ Enabled | false | Toggle Autoscaling support globally for the Argo CD server com HPA | [Object] | HorizontalPodAutoscaler options for the Argo CD Server component. !!! note - When `.spec.server.autoscale.enabled` is set to `true`, the number of required replicas (if set) in `.spec.server.replicas` will be ignored. The final replica count on the server deployment will be controlled by the Horizontal Pod Autoscaler instead. + When `.spec.server.autoscale.enabled` is set to `true`, the number of required replicas (if set) in `.spec.server.replicas` will be ignored. The final replica count on the server deployment will be controlled by the Horizontal Pod Autoscaler instead. ### Server Command Arguments @@ -1449,13 +1447,14 @@ Image | `quay.io/dexidp/dex` | The container image for Dex. This overrides the ` OpenShiftOAuth | false | Enable automatic configuration of OpenShift OAuth authentication for the Dex server. This is ignored if a value is present for `sso.dex.config`. Resources | [Empty] | The container compute resources. Version | v2.21.0 (SHA) | The tag to use with the Dex container image. +Env | [Empty] | Environment to set for Dex. ### Dex Example !!! note `.spec.dex` is no longer supported in Argo CD operator v0.8.0 onwards, use `.spec.sso.dex` instead. -The following examples show all properties set to the default values. +The following examples show all properties set to the default values. ``` yaml apiVersion: argoproj.io/v1alpha1 @@ -1506,7 +1505,7 @@ spec: ### Important Note regarding Role Mappings: -To have a specific user be properly atrributed with the `role:admin` upon SSO through Openshift, the user needs to be in a **group** with the `cluster-admin` role added. If the user only has a direct `ClusterRoleBinding` to the Openshift role for `cluster-admin`, the ArgoCD role will not map. +To have a specific user be properly atrributed with the `role:admin` upon SSO through Openshift, the user needs to be in a **group** with the `cluster-admin` role added. If the user only has a direct `ClusterRoleBinding` to the Openshift role for `cluster-admin`, the ArgoCD role will not map. A quick fix will be to create an `cluster-admins` group, add the user to the group and then apply the `cluster-admin` ClusterRole to the group. @@ -1675,7 +1674,7 @@ spec: ## Banner -The following properties are available for configuring a [UI banner message](https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/#banners). +The following properties are available for configuring a [UI banner message](https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/#banners). Name | Default | Description --- | --- | --- diff --git a/docs/usage/dex.md b/docs/usage/dex.md index 172900487..c20b207a1 100644 --- a/docs/usage/dex.md +++ b/docs/usage/dex.md @@ -11,13 +11,13 @@ Dex can be used to delegate authentication to external identity providers like G ## Installing & Configuring Dex -Dex configuration has moved to `.spec.sso` in release v0.4.0. Dex can be enabled by setting `.spec.sso.provider` to `dex` in the Argo CD CR. +Dex configuration has moved to `.spec.sso` in release v0.4.0. Dex can be enabled by setting `.spec.sso.provider` to `dex` in the Argo CD CR. !!! note - It is now mandatory to specify `.spec.sso.dex` either with OpenShift configuration through `openShiftOAuth: true` or valid custom configuration supplied through `.spec.sso.dex.config`. Absence of either will result in an error due to failing health checks on Dex. + It is now mandatory to specify `.spec.sso.dex` either with OpenShift configuration through `openShiftOAuth: true` or valid custom configuration supplied through `.spec.sso.dex.config`. Absence of either will result in an error due to failing health checks on Dex. !!! note - Specifying `.spec.sso.dex` without setting dex as the provider will result in an error. + Specifying `.spec.sso.dex` without setting dex as the provider will result in an error. !!! note `.spec.dex` is no longer supported in Argo CD operator v0.8.0 onwards, use `.spec.sso.dex` instead. @@ -111,9 +111,47 @@ spec: - name: dummy-org ``` -## Uninstalling Dex +## Use ArgoCD's Dex for Argo Workflows authentication + +The below section describes how to configure Argo CD's Dex to accept authentication requests from Argo Workflows. + +1. Register the application in the identity provider as explained [here](https://argoproj.github.io/argo-cd/operator-manual/user-management/#1-register-the-application-in-the-identity-provider). + +2. Update the Argo CD CR. + +In the `sso.dex.env` key, add the environment variable as shown in the [example manifests for authenticating against Argo CD's Dex](https://argoproj.github.io/argo-workflows/argo-server-sso-argocd/#example-manifests-for-authenticating-against-argo-cds-dex-kustomize). + +``` yaml +apiVersion: argoproj.io/v1alpha1 +kind: ArgoCD +metadata: + name: example-argocd +spec: + sso: + provider: dex + dex: + config: | + connectors: + # GitHub example + - type: github + id: github + name: GitHub + config: + clientID: xxxxxxxxxxxxxx + clientSecret: $dex.github.clientSecret # Alternatively $:dex.github.clientSecret + orgs: + - name: dummy-org + env: + - name: ARGO_WORKFLOWS_SSO_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: argo-workflows-sso + key: client-secret +``` + +## Uninstalling Dex !!! note `DISABLE_DEX` environment variable is no longer supported in Argo CD operator v0.8.0 onwards. -Dex can be uninstalled either by removing `.spec.sso` from the Argo CD CR, or switching to a different SSO provider. +Dex can be uninstalled either by removing `.spec.sso` from the Argo CD CR, or switching to a different SSO provider. diff --git a/tests/k8s/1-015_validate_sso_status/06-assert.yaml b/tests/k8s/1-015_validate_sso_status/06-assert.yaml new file mode 100644 index 000000000..8ee9d232a --- /dev/null +++ b/tests/k8s/1-015_validate_sso_status/06-assert.yaml @@ -0,0 +1,36 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd +spec: + sso: + provider: dex + dex: + config: test-config + env: + - name: ARGO_WORKFLOWS_SSO_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: argo-workflows-sso + key: client-secret +status: + phase: Available + sso: Running +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-dex-server +spec: + template: + spec: + containers: + - name: dex + env: + - name: ARGO_WORKFLOWS_SSO_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: argo-workflows-sso + key: client-secret +status: + readyReplicas: 1 diff --git a/tests/k8s/1-015_validate_sso_status/06-dex-spec-sso-env.yaml b/tests/k8s/1-015_validate_sso_status/06-dex-spec-sso-env.yaml new file mode 100644 index 000000000..dcb2224a2 --- /dev/null +++ b/tests/k8s/1-015_validate_sso_status/06-dex-spec-sso-env.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Secret +metadata: + name: argo-workflows-sso +data: + client-id: YXJnby13b3JrZmxvd3Mtc3Nv + client-secret: aGk= +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + # Patches to add dex as an sso provider and configure the environment variables. + - script: | + kubectl patch -n $NAMESPACE argocd/argocd --type='json' -p='[{"op":"add","path":"/spec/sso","value":{}},{"op":"add","path":"/spec/sso/provider","value":"dex"},{"op":"add","path":"/spec/sso/dex","value":{}},{"op":"add","path":"/spec/sso/dex/config","value":"test-config"},{"op":"add","path":"/spec/sso/dex/env","value":[]},{"op":"add","path":"/spec/sso/dex/env/0","value":{"name":"ARGO_WORKFLOWS_SSO_CLIENT_SECRET","valueFrom":{"secretKeyRef":{"name":"argo-workflows-sso","key":"client-secret"}}}}]' + - script: sleep 10 From 17064c9b310785ab145747a367f7deb5507a572e Mon Sep 17 00:00:00 2001 From: Cheng Fang Date: Thu, 16 Nov 2023 02:53:29 -0500 Subject: [PATCH 37/94] fix: replace deprecated AddToScheme with Install, and deprecated SchemeGroupVersion with GroupVersion. (#1066) Signed-off-by: Cheng Fang --- controllers/argocd/custommapper_test.go | 20 ++++++++++---------- controllers/argocd/keycloak_test.go | 4 ++-- controllers/argocd/route_test.go | 6 +++--- controllers/argocd/secret_test.go | 4 ++-- controllers/argocd/sso.go | 2 +- controllers/argocd/sso_test.go | 10 +++++----- controllers/argocd/status_test.go | 4 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/controllers/argocd/custommapper_test.go b/controllers/argocd/custommapper_test.go index acd32905e..8cfad322e 100644 --- a/controllers/argocd/custommapper_test.go +++ b/controllers/argocd/custommapper_test.go @@ -153,7 +153,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { resObjs := []client.Object{argocd, secret, service} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -210,7 +210,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { resObjs := []client.Object{argocd, secret} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -260,7 +260,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { resObjs := []client.Object{argocd, secret, service} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -290,7 +290,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { resObjs := []client.Object{argocd, secret} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -324,7 +324,7 @@ func TestReconcileArgoCD_tlsSecretMapperRepoServer(t *testing.T) { resObjs := []client.Object{argocd, secret} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -385,7 +385,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { resObjs := []client.Object{argocd, secret, service} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -442,7 +442,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { resObjs := []client.Object{argocd, secret} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -492,7 +492,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { resObjs := []client.Object{argocd, secret, service} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -522,7 +522,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { resObjs := []client.Object{argocd, secret} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -556,7 +556,7 @@ func TestReconcileArgoCD_tlsSecretMapperRedis(t *testing.T) { resObjs := []client.Object{argocd, secret} subresObjs := []client.Object{argocd} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) diff --git a/controllers/argocd/keycloak_test.go b/controllers/argocd/keycloak_test.go index 58670e341..37236dafa 100644 --- a/controllers/argocd/keycloak_test.go +++ b/controllers/argocd/keycloak_test.go @@ -354,7 +354,7 @@ func TestKeycloak_testServerCert(t *testing.T) { resObjs := []client.Object{a} subresObjs := []client.Object{a} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -426,7 +426,7 @@ func TestKeycloakConfigVerifyTLSForOpenShift(t *testing.T) { resObjs := []client.Object{test.argoCD} subresObjs := []client.Object{test.argoCD} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) diff --git a/controllers/argocd/route_test.go b/controllers/argocd/route_test.go index 4b2c6dfb0..626520e55 100644 --- a/controllers/argocd/route_test.go +++ b/controllers/argocd/route_test.go @@ -37,7 +37,7 @@ func TestReconcileRouteSetLabels(t *testing.T) { resObjs := []client.Object{argoCD} subresObjs := []client.Object{argoCD} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -73,7 +73,7 @@ func TestReconcileRouteSetsInsecure(t *testing.T) { resObjs := []client.Object{argoCD} subresObjs := []client.Object{argoCD} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -149,7 +149,7 @@ func TestReconcileRouteUnsetsInsecure(t *testing.T) { resObjs := []client.Object{argoCD} subresObjs := []client.Object{argoCD} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) diff --git a/controllers/argocd/secret_test.go b/controllers/argocd/secret_test.go index f694f43ef..8fbcc0058 100644 --- a/controllers/argocd/secret_test.go +++ b/controllers/argocd/secret_test.go @@ -120,7 +120,7 @@ func Test_ReconcileArgoCD_ReconcileRepoTLSSecret(t *testing.T) { repoDepl, ctrlSts} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -329,7 +329,7 @@ func Test_ReconcileArgoCD_ReconcileRedisTLSSecret(t *testing.T) { ctrlSts, redisDepl} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) diff --git a/controllers/argocd/sso.go b/controllers/argocd/sso.go index 6b3f38172..3acd2ab69 100644 --- a/controllers/argocd/sso.go +++ b/controllers/argocd/sso.go @@ -44,7 +44,7 @@ func IsTemplateAPIAvailable() bool { // verifyTemplateAPI will verify that the template API is present. func verifyTemplateAPI() error { - found, err := argoutil.VerifyAPI(template.SchemeGroupVersion.Group, template.SchemeGroupVersion.Version) + found, err := argoutil.VerifyAPI(template.GroupVersion.Group, template.GroupVersion.Version) if err != nil { return err } diff --git a/controllers/argocd/sso_test.go b/controllers/argocd/sso_test.go index 099a973e0..08d30e07d 100644 --- a/controllers/argocd/sso_test.go +++ b/controllers/argocd/sso_test.go @@ -44,7 +44,7 @@ func TestReconcile_testKeycloakTemplateInstance(t *testing.T) { resObjs := []client.Object{a} subresObjs := []client.Object{a} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -69,7 +69,7 @@ func TestReconcile_noTemplateInstance(t *testing.T) { resObjs := []client.Object{a} subresObjs := []client.Object{a} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -215,7 +215,7 @@ func TestReconcile_illegalSSOConfiguration(t *testing.T) { resObjs := []client.Object{test.argoCD} subresObjs := []client.Object{test.argoCD} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -254,7 +254,7 @@ func TestReconcile_testKeycloakK8sInstance(t *testing.T) { resObjs := []client.Object{a} subresObjs := []client.Object{a} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) @@ -273,7 +273,7 @@ func TestReconcile_testKeycloakInstanceResources(t *testing.T) { resObjs := []client.Object{a} subresObjs := []client.Object{a} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.AddToScheme, oappsv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, templatev1.Install, oappsv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) diff --git a/controllers/argocd/status_test.go b/controllers/argocd/status_test.go index 241120785..78ab78b69 100644 --- a/controllers/argocd/status_test.go +++ b/controllers/argocd/status_test.go @@ -65,7 +65,7 @@ func TestReconcileArgoCD_reconcileStatusKeycloak_OpenShift(t *testing.T) { assert.NoError(t, createNamespace(r, a.Namespace, "")) - assert.NoError(t, oappsv1.AddToScheme(r.Scheme)) + assert.NoError(t, oappsv1.Install(r.Scheme)) templateAPIFound = true defer removeTemplateAPI() @@ -255,7 +255,7 @@ func TestReconcileArgoCD_reconcileStatusHost(t *testing.T) { resObjs := []client.Object{a} subresObjs := []client.Object{a} runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.AddToScheme, routev1.AddToScheme) + sch := makeTestReconcilerScheme(argoproj.AddToScheme, configv1.Install, routev1.Install) cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) r := makeTestReconciler(cl, sch) From 9a294a26292125afda9fe0e4e60efd5c23e73e75 Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:13:23 -0500 Subject: [PATCH 38/94] allow enabling ArgoCD workloads independently (#1021) * allow enabling ArgoCD core workloads independently Signed-off-by: ishitasequeira * fix lint Signed-off-by: ishitasequeira * check for dependent component urls if dependent components are disabled Signed-off-by: ishitasequeira * fix build Signed-off-by: ishitasequeira * fix make bundle Signed-off-by: ishitasequeira * fix tests Signed-off-by: ishitasequeira * Update flags for each component Signed-off-by: ishitasequeira * Update configuration using remote flag Signed-off-by: ishitasequeira * fix CI Signed-off-by: ishitasequeira * Address comments Signed-off-by: ishitasequeira * Addressed feedback Signed-off-by: ishitasequeira * update conversion webhook Signed-off-by: ishitasequeira * fix make build Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira --- api/v1alpha1/argocd_conversion.go | 88 ++++++++++++++++++- api/v1beta1/argocd_types.go | 41 +++++++++ api/v1beta1/zz_generated.deepcopy.go | 35 ++++++++ bundle/manifests/argoproj.io_argocds.yaml | 30 +++++++ config/crd/bases/argoproj.io_argocds.yaml | 30 +++++++ controllers/argocd/applicationset.go | 43 ++++++++- controllers/argocd/deployment.go | 57 ++++++++++-- controllers/argocd/statefulset.go | 19 +++- controllers/argocd/util.go | 17 +++- .../0.8.0/argoproj.io_argocds.yaml | 30 +++++++ 10 files changed, 372 insertions(+), 18 deletions(-) diff --git a/api/v1alpha1/argocd_conversion.go b/api/v1alpha1/argocd_conversion.go index 591924240..3b54e465f 100644 --- a/api/v1alpha1/argocd_conversion.go +++ b/api/v1alpha1/argocd_conversion.go @@ -76,8 +76,8 @@ func (src *ArgoCD) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.Notifications = v1beta1.ArgoCDNotifications(src.Spec.Notifications) dst.Spec.Prometheus = *ConvertAlphaToBetaPrometheus(&src.Spec.Prometheus) dst.Spec.RBAC = v1beta1.ArgoCDRBACSpec(src.Spec.RBAC) - dst.Spec.Redis = v1beta1.ArgoCDRedisSpec(src.Spec.Redis) - dst.Spec.Repo = v1beta1.ArgoCDRepoSpec(src.Spec.Repo) + dst.Spec.Redis = *ConvertAlphaToBetaRedis(&src.Spec.Redis) + dst.Spec.Repo = *ConvertAlphaToBetaRepo(&src.Spec.Repo) dst.Spec.RepositoryCredentials = src.Spec.RepositoryCredentials dst.Spec.ResourceHealthChecks = ConvertAlphaToBetaResourceHealthChecks(src.Spec.ResourceHealthChecks) dst.Spec.ResourceIgnoreDifferences = ConvertAlphaToBetaResourceIgnoreDifferences(src.Spec.ResourceIgnoreDifferences) @@ -143,8 +143,8 @@ func (dst *ArgoCD) ConvertFrom(srcRaw conversion.Hub) error { dst.Spec.Notifications = ArgoCDNotifications(src.Spec.Notifications) dst.Spec.Prometheus = *ConvertBetaToAlphaPrometheus(&src.Spec.Prometheus) dst.Spec.RBAC = ArgoCDRBACSpec(src.Spec.RBAC) - dst.Spec.Redis = ArgoCDRedisSpec(src.Spec.Redis) - dst.Spec.Repo = ArgoCDRepoSpec(src.Spec.Repo) + dst.Spec.Redis = *ConvertBetaToAlphaRedis(&src.Spec.Redis) + dst.Spec.Repo = *ConvertBetaToAlphaRepo(&src.Spec.Repo) dst.Spec.RepositoryCredentials = src.Spec.RepositoryCredentials dst.Spec.ResourceHealthChecks = ConvertBetaToAlphaResourceHealthChecks(src.Spec.ResourceHealthChecks) dst.Spec.ResourceIgnoreDifferences = ConvertBetaToAlphaResourceIgnoreDifferences(src.Spec.ResourceIgnoreDifferences) @@ -184,6 +184,46 @@ func ConvertAlphaToBetaController(src *ArgoCDApplicationControllerSpec) *v1beta1 return dst } +func ConvertAlphaToBetaRedis(src *ArgoCDRedisSpec) *v1beta1.ArgoCDRedisSpec { + var dst *v1beta1.ArgoCDRedisSpec + if src != nil { + dst = &v1beta1.ArgoCDRedisSpec{ + AutoTLS: src.AutoTLS, + DisableTLSVerification: src.DisableTLSVerification, + Image: src.Image, + Resources: src.Resources, + Version: src.Version, + } + } + return dst +} + +func ConvertAlphaToBetaRepo(src *ArgoCDRepoSpec) *v1beta1.ArgoCDRepoSpec { + var dst *v1beta1.ArgoCDRepoSpec + if src != nil { + dst = &v1beta1.ArgoCDRepoSpec{ + AutoTLS: src.AutoTLS, + Env: src.Env, + ExecTimeout: src.ExecTimeout, + ExtraRepoCommandArgs: src.ExtraRepoCommandArgs, + Image: src.Image, + InitContainers: src.InitContainers, + LogFormat: src.LogFormat, + LogLevel: src.LogLevel, + MountSAToken: src.MountSAToken, + Replicas: src.Replicas, + Resources: src.Resources, + ServiceAccount: src.ServiceAccount, + SidecarContainers: src.SidecarContainers, + VerifyTLS: src.VerifyTLS, + Version: src.Version, + VolumeMounts: src.VolumeMounts, + Volumes: src.Volumes, + } + } + return dst +} + func ConvertAlphaToBetaWebhookServer(src *WebhookServerSpec) *v1beta1.WebhookServerSpec { var dst *v1beta1.WebhookServerSpec if src != nil { @@ -604,3 +644,43 @@ func ConvertBetaToAlphaResourceHealthChecks(src []v1beta1.ResourceHealthCheck) [ } return dst } + +func ConvertBetaToAlphaRedis(src *v1beta1.ArgoCDRedisSpec) *ArgoCDRedisSpec { + var dst *ArgoCDRedisSpec + if src != nil { + dst = &ArgoCDRedisSpec{ + AutoTLS: src.AutoTLS, + DisableTLSVerification: src.DisableTLSVerification, + Image: src.Image, + Resources: src.Resources, + Version: src.Version, + } + } + return dst +} + +func ConvertBetaToAlphaRepo(src *v1beta1.ArgoCDRepoSpec) *ArgoCDRepoSpec { + var dst *ArgoCDRepoSpec + if src != nil { + dst = &ArgoCDRepoSpec{ + AutoTLS: src.AutoTLS, + Env: src.Env, + ExecTimeout: src.ExecTimeout, + ExtraRepoCommandArgs: src.ExtraRepoCommandArgs, + Image: src.Image, + InitContainers: src.InitContainers, + LogFormat: src.LogFormat, + LogLevel: src.LogLevel, + MountSAToken: src.MountSAToken, + Replicas: src.Replicas, + Resources: src.Resources, + ServiceAccount: src.ServiceAccount, + SidecarContainers: src.SidecarContainers, + VerifyTLS: src.VerifyTLS, + Version: src.Version, + VolumeMounts: src.VolumeMounts, + Volumes: src.Volumes, + } + } + return dst +} diff --git a/api/v1beta1/argocd_types.go b/api/v1beta1/argocd_types.go index 7a401eba4..a7d72b532 100644 --- a/api/v1beta1/argocd_types.go +++ b/api/v1beta1/argocd_types.go @@ -108,6 +108,13 @@ type ArgoCDApplicationControllerSpec struct { // Env lets you specify environment for application controller pods Env []corev1.EnvVar `json:"env,omitempty"` + + // Enabled is the flag to enable the Application Controller during ArgoCD installation. (optional, default `true`) + Enabled *bool `json:"enabled,omitempty"` +} + +func (a *ArgoCDApplicationControllerSpec) IsEnabled() bool { + return a.Enabled == nil || (a.Enabled != nil && *a.Enabled) } // ArgoCDApplicationControllerShardSpec defines the options available for enabling sharding for the Application Controller component. @@ -162,6 +169,13 @@ type ArgoCDApplicationSet struct { // SCMRootCAConfigMap is the name of the config map that stores the Gitlab SCM Provider's TLS certificate which will be mounted on the ApplicationSet Controller (optional). SCMRootCAConfigMap string `json:"scmRootCAConfigMap,omitempty"` + + // Enabled is the flag to enable the Application Set Controller during ArgoCD installation. (optional, default `true`) + Enabled *bool `json:"enabled,omitempty"` +} + +func (a *ArgoCDApplicationSet) IsEnabled() bool { + return a.Enabled == nil || (a.Enabled != nil && *a.Enabled) } // ArgoCDCASpec defines the CA options for ArgCD. @@ -413,6 +427,16 @@ type ArgoCDRedisSpec struct { // The value specified here can currently be: // - openshift - Use the OpenShift service CA to request TLS config AutoTLS string `json:"autotls,omitempty"` + + // Enabled is the flag to enable Redis during ArgoCD installation. (optional, default `true`) + Enabled *bool `json:"enabled,omitempty"` + + // Remote specifies the remote URL of the Redis container. (optional, by default, a local instance managed by the operator is used.) + Remote *string `json:"remote,omitempty"` +} + +func (a *ArgoCDRedisSpec) IsEnabled() bool { + return a.Enabled == nil || (a.Enabled != nil && *a.Enabled) } // ArgoCDRepoSpec defines the desired state for the Argo CD repo server component. @@ -473,6 +497,16 @@ type ArgoCDRepoSpec struct { // SidecarContainers defines the list of sidecar containers for the repo server deployment SidecarContainers []corev1.Container `json:"sidecarContainers,omitempty"` + + // Enabled is the flag to enable Repo Server during ArgoCD installation. (optional, default `true`) + Enabled *bool `json:"enabled,omitempty"` + + // Remote specifies the remote URL of the Repo Server container. (optional, by default, a local instance managed by the operator is used.) + Remote *string `json:"remote,omitempty"` +} + +func (a *ArgoCDRepoSpec) IsEnabled() bool { + return a.Enabled == nil || (a.Enabled != nil && *a.Enabled) } // ArgoCDRouteSpec defines the desired state for an OpenShift Route. @@ -563,6 +597,13 @@ type ArgoCDServerSpec struct { // ExtraCommandArgs will not be added, if one of these commands is already part of the server command // with same or different value. ExtraCommandArgs []string `json:"extraCommandArgs,omitempty"` + + // Enabled is the flag to enable ArgoCD Server during ArgoCD installation. (optional, default `true`) + Enabled *bool `json:"enabled,omitempty"` +} + +func (a *ArgoCDServerSpec) IsEnabled() bool { + return a.Enabled == nil || (a.Enabled != nil && *a.Enabled) } // ArgoCDServerServiceSpec defines the Service options for Argo CD Server component. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index cf6ca277c..cdb36778e 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -114,6 +114,11 @@ func (in *ArgoCDApplicationControllerSpec) DeepCopyInto(out *ArgoCDApplicationCo (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDApplicationControllerSpec. @@ -147,6 +152,11 @@ func (in *ArgoCDApplicationSet) DeepCopyInto(out *ArgoCDApplicationSet) { (*in).DeepCopyInto(*out) } in.WebhookServer.DeepCopyInto(&out.WebhookServer) + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDApplicationSet. @@ -520,6 +530,16 @@ func (in *ArgoCDRedisSpec) DeepCopyInto(out *ArgoCDRedisSpec) { *out = new(v1.ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Remote != nil { + in, out := &in.Remote, &out.Remote + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDRedisSpec. @@ -590,6 +610,16 @@ func (in *ArgoCDRepoSpec) DeepCopyInto(out *ArgoCDRepoSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Remote != nil { + in, out := &in.Remote, &out.Remote + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDRepoSpec. @@ -747,6 +777,11 @@ func (in *ArgoCDServerSpec) DeepCopyInto(out *ArgoCDServerSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArgoCDServerSpec. diff --git a/bundle/manifests/argoproj.io_argocds.yaml b/bundle/manifests/argoproj.io_argocds.yaml index 82cd8b2ad..242e229ee 100644 --- a/bundle/manifests/argoproj.io_argocds.yaml +++ b/bundle/manifests/argoproj.io_argocds.yaml @@ -6990,6 +6990,10 @@ spec: description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed. properties: + enabled: + description: Enabled is the flag to enable the Application Set + Controller during ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for applicationSet controller pods @@ -7342,6 +7346,10 @@ spec: to a duration, e.g. 10m or 600s to control the synchronisation frequency." type: string + enabled: + description: Enabled is the flag to enable the Application Controller + during ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for application controller pods @@ -8358,9 +8366,18 @@ spec: description: DisableTLSVerification defines whether redis server API should be accessed using strict TLS validation type: boolean + enabled: + description: Enabled is the flag to enable Redis during ArgoCD + installation. (optional, default `true`) + type: boolean image: description: Image is the Redis container image. type: string + remote: + description: Remote specifies the remote URL of the Redis container. + (optional, by default, a local instance managed by the operator + is used.) + type: string resources: description: Resources defines the Compute Resources required by the container for Redis. @@ -8424,6 +8441,10 @@ spec: can currently be: - openshift - Use the OpenShift service CA to request TLS config' type: string + enabled: + description: Enabled is the flag to enable Repo Server during + ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for repo server pods @@ -9882,6 +9903,11 @@ spec: description: MountSAToken describes whether you would like to have the Repo server mount the service account token type: boolean + remote: + description: Remote specifies the remote URL of the Repo Server + container. (optional, by default, a local instance managed by + the operator is used.) + type: string replicas: description: Replicas defines the number of replicas for argocd-repo-server. Value should be greater than or equal to 0. Default is nil. @@ -13067,6 +13093,10 @@ spec: required: - enabled type: object + enabled: + description: Enabled is the flag to enable ArgoCD Server during + ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for API server pods items: diff --git a/config/crd/bases/argoproj.io_argocds.yaml b/config/crd/bases/argoproj.io_argocds.yaml index 98a1c8fdc..67b2103e6 100644 --- a/config/crd/bases/argoproj.io_argocds.yaml +++ b/config/crd/bases/argoproj.io_argocds.yaml @@ -6981,6 +6981,10 @@ spec: description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed. properties: + enabled: + description: Enabled is the flag to enable the Application Set + Controller during ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for applicationSet controller pods @@ -7333,6 +7337,10 @@ spec: to a duration, e.g. 10m or 600s to control the synchronisation frequency." type: string + enabled: + description: Enabled is the flag to enable the Application Controller + during ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for application controller pods @@ -8349,9 +8357,18 @@ spec: description: DisableTLSVerification defines whether redis server API should be accessed using strict TLS validation type: boolean + enabled: + description: Enabled is the flag to enable Redis during ArgoCD + installation. (optional, default `true`) + type: boolean image: description: Image is the Redis container image. type: string + remote: + description: Remote specifies the remote URL of the Redis container. + (optional, by default, a local instance managed by the operator + is used.) + type: string resources: description: Resources defines the Compute Resources required by the container for Redis. @@ -8415,6 +8432,10 @@ spec: can currently be: - openshift - Use the OpenShift service CA to request TLS config' type: string + enabled: + description: Enabled is the flag to enable Repo Server during + ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for repo server pods @@ -9873,6 +9894,11 @@ spec: description: MountSAToken describes whether you would like to have the Repo server mount the service account token type: boolean + remote: + description: Remote specifies the remote URL of the Repo Server + container. (optional, by default, a local instance managed by + the operator is used.) + type: string replicas: description: Replicas defines the number of replicas for argocd-repo-server. Value should be greater than or equal to 0. Default is nil. @@ -13058,6 +13084,10 @@ spec: required: - enabled type: object + enabled: + description: Enabled is the flag to enable ArgoCD Server during + ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for API server pods items: diff --git a/controllers/argocd/applicationset.go b/controllers/argocd/applicationset.go index 8e3f62205..dded2ebcd 100644 --- a/controllers/argocd/applicationset.go +++ b/controllers/argocd/applicationset.go @@ -44,8 +44,11 @@ func getArgoApplicationSetCommand(cr *argoproj.ArgoCD) []string { cmd = append(cmd, "entrypoint.sh") cmd = append(cmd, "argocd-applicationset-controller") - cmd = append(cmd, "--argocd-repo-server") - cmd = append(cmd, getRepoServerAddress(cr)) + if cr.Spec.Repo.IsEnabled() { + cmd = append(cmd, "--argocd-repo-server", getRepoServerAddress(cr)) + } else { + log.Info("Repo Server is disabled. This would affect the functioning of ApplicationSet Controller.") + } cmd = append(cmd, "--loglevel") cmd = append(cmd, getLogLevel(cr.Spec.ApplicationSet.LogLevel)) @@ -178,6 +181,11 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, if existing := newDeploymentWithSuffix("applicationset-controller", "controller", cr); argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + if !cr.Spec.ApplicationSet.IsEnabled() { + err := r.Client.Delete(context.TODO(), existing) + return err + } + existingSpec := existing.Spec.Template.Spec deploymentsDifferent := !reflect.DeepEqual(existingSpec.Containers[0], podSpec.Containers) || @@ -204,6 +212,10 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, return nil // Deployment found with nothing to do, move along... } + if !cr.Spec.ApplicationSet.IsEnabled() { + return nil + } + if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { return err } @@ -301,6 +313,10 @@ func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoproj.Arg } if exists { + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + err := r.Client.Delete(context.TODO(), sa) + return nil, err + } return sa, nil } @@ -308,6 +324,10 @@ func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoproj.Arg return nil, err } + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil, nil + } + err := r.Client.Create(context.TODO(), sa) if err != nil { return nil, err @@ -408,9 +428,18 @@ func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoproj.ArgoCD) (*v1. if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { return nil, err } + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + err1 := r.Client.Delete(context.TODO(), role) + return nil, err1 + } return role, r.Client.Create(context.TODO(), role) } + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + err := r.Client.Delete(context.TODO(), role) + return nil, err + } + role.Rules = policyRules if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { return nil, err @@ -429,11 +458,19 @@ func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoproj.ArgoCD roleBindingExists := true if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: roleBinding.Name, Namespace: cr.Namespace}, roleBinding); err != nil { if !errors.IsNotFound(err) { + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil + } return fmt.Errorf("failed to get the rolebinding associated with %s : %s", name, err) } roleBindingExists = false } + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + err := r.Client.Delete(context.TODO(), roleBinding) + return err + } + setAppSetLabels(&roleBinding.ObjectMeta) roleBinding.RoleRef = v1.RoleRef{ @@ -513,7 +550,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) er log.Info("reconciling applicationset service") svc := newServiceWithSuffix(common.ApplicationSetServiceNameSuffix, common.ApplicationSetServiceNameSuffix, cr) - if cr.Spec.ApplicationSet == nil { + if cr.Spec.ApplicationSet == nil || !cr.Spec.ApplicationSet.IsEnabled() { if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { err := argoutil.FetchObject(r.Client, cr.Namespace, svc.Name, svc) diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go index 6b247c9c8..a99d8ecaf 100644 --- a/controllers/argocd/deployment.go +++ b/controllers/argocd/deployment.go @@ -232,9 +232,11 @@ func getArgoRepoCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { cmd = append(cmd, "uid_entrypoint.sh") cmd = append(cmd, "argocd-repo-server") - cmd = append(cmd, "--redis") - cmd = append(cmd, getRedisServerAddress(cr)) - + if cr.Spec.Redis.IsEnabled() { + cmd = append(cmd, "--redis", getRedisServerAddress(cr)) + } else { + log.Info("Redis is Disabled. Skipping adding Redis configuration to Repo Server.") + } if useTLSForRedis { cmd = append(cmd, "--redis-use-tls") if isRedisTLSVerificationDisabled(cr) { @@ -291,11 +293,17 @@ func getArgoServerCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { cmd = append(cmd, "--dex-server") cmd = append(cmd, getDexServerAddress(cr)) - cmd = append(cmd, "--repo-server") - cmd = append(cmd, getRepoServerAddress(cr)) + if cr.Spec.Repo.IsEnabled() { + cmd = append(cmd, "--repo-server", getRepoServerAddress(cr)) + } else { + log.Info("Repo Server is disabled. This would affect the functioning of ArgoCD Server.") + } - cmd = append(cmd, "--redis") - cmd = append(cmd, getRedisServerAddress(cr)) + if cr.Spec.Redis.IsEnabled() { + cmd = append(cmd, "--redis", getRedisServerAddress(cr)) + } else { + log.Info("Redis is Disabled. Skipping adding Redis configuration to ArgoCD Server.") + } if useTLSForRedis { cmd = append(cmd, "--redis-use-tls") @@ -348,6 +356,9 @@ func getDexServerAddress(cr *argoproj.ArgoCD) string { // getRepoServerAddress will return the Argo CD repo server address. func getRepoServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.Repo.Remote != nil && *cr.Spec.Repo.Remote != "" { + return *cr.Spec.Repo.Remote + } return fqdnServiceRef("repo-server", common.ArgoCDDefaultRepoServerPort, cr) } @@ -624,6 +635,11 @@ func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoproj.ArgoCD, useTLS b existing := newDeploymentWithSuffix("redis", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + if !cr.Spec.Redis.IsEnabled() { + // Deployment exists but component enabled flag has been set to false, delete the Deployment + log.Info("Redis exists but should be disabled. Deleting existing redis.") + return r.Client.Delete(context.TODO(), deploy) + } if cr.Spec.HA.Enabled { // Deployment exists but HA enabled flag has been set to true, delete the Deployment return r.Client.Delete(context.TODO(), deploy) @@ -660,6 +676,11 @@ func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoproj.ArgoCD, useTLS b return nil // Deployment found with nothing to do, move along... } + if !cr.Spec.Redis.IsEnabled() { + log.Info("Redis disabled. Skipping starting redis.") + return nil + } + if cr.Spec.HA.Enabled { return nil // HA enabled, do nothing. } @@ -1103,6 +1124,13 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSFor existing := newDeploymentWithSuffix("repo-server", "repo-server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + + if !cr.Spec.Repo.IsEnabled() { + log.Info("Existing ArgoCD Repo Server found but should be disabled. Deleting Repo Server") + // Delete existing deployment for ArgoCD Repo Server, if any .. + return nil + } + changed := false actualImage := existing.Spec.Template.Spec.Containers[0].Image desiredImage := getRepoServerContainerImage(cr) @@ -1171,6 +1199,11 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSFor return nil // Deployment found with nothing to do, move along... } + if !cr.Spec.Repo.IsEnabled() { + log.Info("ArgoCD Repo Server disabled. Skipping starting ArgoCD Repo Server.") + return nil + } + if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { return err } @@ -1292,6 +1325,11 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSF existing := newDeploymentWithSuffix("server", "server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + if !cr.Spec.Server.IsEnabled() { + log.Info("Existing ArgoCD Server found but should be disabled. Deleting ArgoCD Server") + // Delete existing deployment for ArgoCD Server, if any .. + return nil + } actualImage := existing.Spec.Template.Spec.Containers[0].Image desiredImage := getArgoContainerImage(cr) changed := false @@ -1337,6 +1375,11 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSF return nil // Deployment found with nothing to do, move along... } + if !cr.Spec.Controller.IsEnabled() { + log.Info("ArgoCD Repo Server disabled. Skipping starting repo server.") + return nil + } + if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { return err } diff --git a/controllers/argocd/statefulset.go b/controllers/argocd/statefulset.go index 0cefa8463..a0d16e9cd 100644 --- a/controllers/argocd/statefulset.go +++ b/controllers/argocd/statefulset.go @@ -391,8 +391,8 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoproj.ArgoCD) error { existing := newStatefulSetWithSuffix("redis-ha-server", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { - if !cr.Spec.HA.Enabled { - // StatefulSet exists but HA enabled flag has been set to false, delete the StatefulSet + if !(cr.Spec.HA.Enabled && cr.Spec.Redis.IsEnabled()) { + // StatefulSet exists but either HA or component enabled flag has been set to false, delete the StatefulSet return r.Client.Delete(context.TODO(), existing) } @@ -424,6 +424,11 @@ func (r *ReconcileArgoCD) reconcileRedisStatefulSet(cr *argoproj.ArgoCD) error { return nil // StatefulSet found, do nothing } + if !cr.Spec.Redis.IsEnabled() { + log.Info("Redis disabled. Skipping starting Redis.") // Redis not enabled, do nothing. + return nil + } + if !cr.Spec.HA.Enabled { return nil // HA not enabled, do nothing. } @@ -649,6 +654,11 @@ func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj existing := newStatefulSetWithSuffix("application-controller", "application-controller", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + if !cr.Spec.Controller.IsEnabled() { + log.Info("Existing application controller found but should be disabled. Deleting Application Controller") + // Delete existing deployment for Application Controller, if any .. + return r.Client.Delete(context.TODO(), existing) + } actualImage := existing.Spec.Template.Spec.Containers[0].Image desiredImage := getArgoContainerImage(cr) changed := false @@ -696,6 +706,11 @@ func (r *ReconcileArgoCD) reconcileApplicationControllerStatefulSet(cr *argoproj return nil // StatefulSet found with nothing to do, move along... } + if !cr.Spec.Controller.IsEnabled() { + log.Info("Application Controller disabled. Skipping starting application controller.") + return nil + } + // Delete existing deployment for Application Controller, if any .. deploy := newDeploymentWithSuffix("application-controller", "application-controller", cr) if argoutil.IsObjectFound(r.Client, deploy.Namespace, deploy.Name, deploy) { diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index c740fd096..8c093fcf4 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -119,7 +119,12 @@ func getArgoApplicationControllerCommand(cr *argoproj.ArgoCD, useTLSForRedis boo cmd := []string{ "argocd-application-controller", "--operation-processors", fmt.Sprint(getArgoServerOperationProcessors(cr)), - "--redis", getRedisServerAddress(cr), + } + + if cr.Spec.Redis.IsEnabled() { + cmd = append(cmd, "--redis", getRedisServerAddress(cr)) + } else { + log.Info("Redis is Disabled. Skipping adding Redis configuration to Application Controller.") } if useTLSForRedis { @@ -131,7 +136,12 @@ func getArgoApplicationControllerCommand(cr *argoproj.ArgoCD, useTLSForRedis boo } } - cmd = append(cmd, "--repo-server", getRepoServerAddress(cr)) + if cr.Spec.Repo.IsEnabled() { + cmd = append(cmd, "--repo-server", getRepoServerAddress(cr)) + } else { + log.Info("Repo Server is disabled. This would affect the functioning of Application Controller.") + } + cmd = append(cmd, "--status-processors", fmt.Sprint(getArgoServerStatusProcessors(cr))) cmd = append(cmd, "--kubectl-parallelism-limit", fmt.Sprint(getArgoControllerParellismLimit(cr))) @@ -580,6 +590,9 @@ func getSentinelLivenessScript(useTLSForRedis bool) string { // getRedisServerAddress will return the Redis service address for the given ArgoCD. func getRedisServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.Redis.Remote != nil && *cr.Spec.Redis.Remote != "" { + return *cr.Spec.Redis.Remote + } if cr.Spec.HA.Enabled { return getRedisHAProxyAddress(cr) } diff --git a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml index 82cd8b2ad..242e229ee 100644 --- a/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml +++ b/deploy/olm-catalog/argocd-operator/0.8.0/argoproj.io_argocds.yaml @@ -6990,6 +6990,10 @@ spec: description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet controller should be installed. properties: + enabled: + description: Enabled is the flag to enable the Application Set + Controller during ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for applicationSet controller pods @@ -7342,6 +7346,10 @@ spec: to a duration, e.g. 10m or 600s to control the synchronisation frequency." type: string + enabled: + description: Enabled is the flag to enable the Application Controller + during ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for application controller pods @@ -8358,9 +8366,18 @@ spec: description: DisableTLSVerification defines whether redis server API should be accessed using strict TLS validation type: boolean + enabled: + description: Enabled is the flag to enable Redis during ArgoCD + installation. (optional, default `true`) + type: boolean image: description: Image is the Redis container image. type: string + remote: + description: Remote specifies the remote URL of the Redis container. + (optional, by default, a local instance managed by the operator + is used.) + type: string resources: description: Resources defines the Compute Resources required by the container for Redis. @@ -8424,6 +8441,10 @@ spec: can currently be: - openshift - Use the OpenShift service CA to request TLS config' type: string + enabled: + description: Enabled is the flag to enable Repo Server during + ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for repo server pods @@ -9882,6 +9903,11 @@ spec: description: MountSAToken describes whether you would like to have the Repo server mount the service account token type: boolean + remote: + description: Remote specifies the remote URL of the Repo Server + container. (optional, by default, a local instance managed by + the operator is used.) + type: string replicas: description: Replicas defines the number of replicas for argocd-repo-server. Value should be greater than or equal to 0. Default is nil. @@ -13067,6 +13093,10 @@ spec: required: - enabled type: object + enabled: + description: Enabled is the flag to enable ArgoCD Server during + ArgoCD installation. (optional, default `true`) + type: boolean env: description: Env lets you specify environment for API server pods items: From 18a0a8d7e78367763ac4e0c0f527db5af33fbe54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:04:15 +0530 Subject: [PATCH 39/94] chore(deps): bump argoproj/argocd in /build/util (#1080) Bumps argoproj/argocd from `d40da8f` to `644c386`. --- updated-dependencies: - dependency-name: argoproj/argocd dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build/util/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/util/Dockerfile b/build/util/Dockerfile index 72bf1fae5..43d153f64 100644 --- a/build/util/Dockerfile +++ b/build/util/Dockerfile @@ -1,5 +1,5 @@ # Argo CD v2.8.3 -FROM quay.io/argoproj/argocd@sha256:d40da8f5747415eb7f9b5c2d9b645aecd423888cad9b36e4f986bff8ecf0a786 as argocd +FROM quay.io/argoproj/argocd@sha256:644c386facf25940291f8e41330422c203240bc0d7da484405cf8fc6c766fe8f as argocd # Final Image FROM docker.io/library/ubuntu:22.04 From a78a8420bb2c525c6fc3ec8886f87854e5886510 Mon Sep 17 00:00:00 2001 From: Abhishek Veeramalla Date: Fri, 24 Nov 2023 14:17:13 +0530 Subject: [PATCH 40/94] feat: upgrade Argo CD for release v.9.0 (#1082) * feat: upgrade Argo CD for release v.9.0 Signed-off-by: iam-veeramalla * fix: unit test failures Signed-off-by: iam-veeramalla --------- Signed-off-by: iam-veeramalla --- Makefile | 2 +- build/util/Dockerfile | 4 +- ...argocd-operator.clusterserviceversion.yaml | 6 +- .../manifests/argoproj.io_applications.yaml | 389 +- .../argoproj.io_applicationsets.yaml | 1495 +- bundle/manifests/argoproj.io_appprojects.yaml | 8 +- common/defaults.go | 2 +- .../crd/bases/argoproj.io_applications.yaml | 391 +- .../bases/argoproj.io_applicationsets.yaml | 1497 +- config/crd/bases/argoproj.io_appprojects.yaml | 8 +- config/manager/kustomization.yaml | 2 +- controllers/argocd/dex_test.go | 2 +- ...er-manager-metrics-service_v1_service.yaml | 16 + ...-operator-manager-config_v1_configmap.yaml | 17 + ...c.authorization.k8s.io_v1_clusterrole.yaml | 10 + ...d-operator-webhook-service_v1_service.yaml | 14 + ...operator.v0.9.0.clusterserviceversion.yaml | 1849 ++ .../0.9.0/argoproj.io_applications.yaml | 4869 +++++ .../0.9.0/argoproj.io_applicationsets.yaml | 15057 ++++++++++++++++ .../0.9.0/argoproj.io_appprojects.yaml | 331 + .../0.9.0/argoproj.io_argocdexports.yaml | 300 + .../0.9.0/argoproj.io_argocds.yaml | 13909 ++++++++++++++ .../03-change-appset-image.yaml | 2 +- 23 files changed, 40126 insertions(+), 54 deletions(-) create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-manager-config_v1_configmap.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-webhook-service_v1_service.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator.v0.9.0.clusterserviceversion.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applications.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applicationsets.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_appprojects.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocdexports.yaml create mode 100644 deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocds.yaml diff --git a/Makefile b/Makefile index 7cb643818..638d5ebd6 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.8.0 +VERSION ?= 0.9.0 # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") diff --git a/build/util/Dockerfile b/build/util/Dockerfile index 43d153f64..3e1b13e45 100644 --- a/build/util/Dockerfile +++ b/build/util/Dockerfile @@ -1,5 +1,5 @@ -# Argo CD v2.8.3 -FROM quay.io/argoproj/argocd@sha256:644c386facf25940291f8e41330422c203240bc0d7da484405cf8fc6c766fe8f as argocd +# Argo CD v2.9.2 +FROM quay.io/argoproj/argocd@sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc as argocd # Final Image FROM docker.io/library/ubuntu:22.04 diff --git a/bundle/manifests/argocd-operator.clusterserviceversion.yaml b/bundle/manifests/argocd-operator.clusterserviceversion.yaml index 5301692cb..c9f758a34 100644 --- a/bundle/manifests/argocd-operator.clusterserviceversion.yaml +++ b/bundle/manifests/argocd-operator.clusterserviceversion.yaml @@ -223,7 +223,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/argoproj-labs/argocd-operator support: Argo CD - name: argocd-operator.v0.8.0 + name: argocd-operator.v0.9.0 namespace: placeholder spec: apiservicedefinitions: {} @@ -1742,7 +1742,7 @@ spec: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: ENABLE_CONVERSION_WEBHOOK value: "true" - image: quay.io/argoprojlabs/argocd-operator:v0.8.0 + image: quay.io/argoprojlabs/argocd-operator:v0.9.0 livenessProbe: httpGet: path: /healthz @@ -1833,7 +1833,7 @@ spec: provider: name: Argo CD Community replaces: argocd-operator.v0.7.0 - version: 0.8.0 + version: 0.9.0 webhookdefinitions: - admissionReviewVersions: - v1alpha1 diff --git a/bundle/manifests/argoproj.io_applications.yaml b/bundle/manifests/argoproj.io_applications.yaml index 79c4b81db..054c1f6d3 100644 --- a/bundle/manifests/argoproj.io_applications.yaml +++ b/bundle/manifests/argoproj.io_applications.yaml @@ -349,6 +349,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -647,6 +678,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -787,7 +849,8 @@ spec: properties: name: description: Name is an alternate way of specifying the target - cluster by its symbolic name + cluster by its symbolic name. This must be set if Server is + not set. type: string namespace: description: Namespace specifies the target namespace for the @@ -795,8 +858,9 @@ spec: namespace-scoped resources that have not set a value for .metadata.namespace type: string server: - description: Server specifies the URL of the target cluster and - must be set to the Kubernetes control plane API + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is not + set. type: string type: object ignoreDifferences: @@ -1057,6 +1121,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -1345,6 +1440,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -1786,6 +1912,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -2087,6 +2244,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -2532,6 +2720,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -2850,6 +3069,38 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize + patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -3282,6 +3533,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -3593,6 +3875,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -3794,7 +4107,8 @@ spec: properties: name: description: Name is an alternate way of specifying the - target cluster by its symbolic name + target cluster by its symbolic name. This must be set + if Server is not set. type: string namespace: description: Namespace specifies the target namespace @@ -3803,8 +4117,9 @@ spec: not set a value for .metadata.namespace type: string server: - description: Server specifies the URL of the target cluster - and must be set to the Kubernetes control plane API + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name + is not set. type: string type: object ignoreDifferences: @@ -4046,6 +4361,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -4357,6 +4703,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications diff --git a/bundle/manifests/argoproj.io_applicationsets.yaml b/bundle/manifests/argoproj.io_applicationsets.yaml index 0b351c7b8..1d20af480 100644 --- a/bundle/manifests/argoproj.io_applicationsets.yaml +++ b/bundle/manifests/argoproj.io_applicationsets.yaml @@ -259,6 +259,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -439,6 +469,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -778,6 +838,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -958,6 +1048,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1301,6 +1421,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1481,6 +1631,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1804,6 +1984,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1984,6 +2194,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -2331,6 +2571,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -2511,6 +2781,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -2850,6 +3150,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3030,6 +3360,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3367,12 +3727,42 @@ spec: items: type: string type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3553,6 +3943,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3876,6 +4296,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -4056,6 +4506,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -4389,6 +4869,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -4569,6 +5079,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5082,6 +5622,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5262,6 +5832,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5554,6 +6154,8 @@ spec: type: string group: type: string + includeSharedProjects: + type: boolean includeSubgroups: type: boolean insecure: @@ -5568,6 +6170,8 @@ spec: - key - secretName type: object + topic: + type: string required: - group type: object @@ -5766,6 +6370,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5946,6 +6580,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6283,6 +6947,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6463,6 +7157,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6804,12 +7528,42 @@ spec: items: type: string type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6990,6 +7744,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -7329,6 +8113,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -7509,6 +8323,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -7852,6 +8696,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8032,6 +8906,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8355,6 +9259,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8535,6 +9469,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8868,6 +9832,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -9048,6 +10042,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -9561,6 +10585,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -9741,6 +10795,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10033,6 +11117,8 @@ spec: type: string group: type: string + includeSharedProjects: + type: boolean includeSubgroups: type: boolean insecure: @@ -10047,6 +11133,8 @@ spec: - key - secretName type: object + topic: + type: string required: - group type: object @@ -10245,6 +11333,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10425,6 +11543,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10766,6 +11914,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10946,6 +12124,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -11276,6 +12484,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -11456,6 +12694,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -11969,6 +13237,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12149,6 +13447,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12441,6 +13769,8 @@ spec: type: string group: type: string + includeSharedProjects: + type: boolean includeSubgroups: type: boolean insecure: @@ -12455,6 +13785,8 @@ spec: - key - secretName type: object + topic: + type: string required: - group type: object @@ -12653,6 +13985,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12833,6 +14195,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12984,12 +14376,31 @@ spec: items: type: string type: array + ignoreApplicationDifferences: + items: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + name: + type: string + type: object + type: array preservedFields: properties: annotations: items: type: string type: array + labels: + items: + type: string + type: array type: object strategy: properties: @@ -13226,6 +14637,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -13406,6 +14847,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: diff --git a/bundle/manifests/argoproj.io_appprojects.yaml b/bundle/manifests/argoproj.io_appprojects.yaml index 8504d6ff0..7dd864ed1 100644 --- a/bundle/manifests/argoproj.io_appprojects.yaml +++ b/bundle/manifests/argoproj.io_appprojects.yaml @@ -89,7 +89,8 @@ spec: properties: name: description: Name is an alternate way of specifying the target - cluster by its symbolic name + cluster by its symbolic name. This must be set if Server is + not set. type: string namespace: description: Namespace specifies the target namespace for the @@ -97,8 +98,9 @@ spec: namespace-scoped resources that have not set a value for .metadata.namespace type: string server: - description: Server specifies the URL of the target cluster - and must be set to the Kubernetes control plane API + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is + not set. type: string type: object type: array diff --git a/common/defaults.go b/common/defaults.go index e74b3807d..13768aa95 100644 --- a/common/defaults.go +++ b/common/defaults.go @@ -61,7 +61,7 @@ const ( ArgoCDDefaultArgoImage = "quay.io/argoproj/argocd" // ArgoCDDefaultArgoVersion is the Argo CD container image digest to use when version not specified. - ArgoCDDefaultArgoVersion = "sha256:d40da8f5747415eb7f9b5c2d9b645aecd423888cad9b36e4f986bff8ecf0a786" // v2.8.3 + ArgoCDDefaultArgoVersion = "sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc" // v2.9.2 // ArgoCDDefaultBackupKeyLength is the length of the generated default backup key. ArgoCDDefaultBackupKeyLength = 32 diff --git a/config/crd/bases/argoproj.io_applications.yaml b/config/crd/bases/argoproj.io_applications.yaml index fc6282dd3..20262bbb6 100644 --- a/config/crd/bases/argoproj.io_applications.yaml +++ b/config/crd/bases/argoproj.io_applications.yaml @@ -348,6 +348,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -646,6 +677,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -786,7 +848,8 @@ spec: properties: name: description: Name is an alternate way of specifying the target - cluster by its symbolic name + cluster by its symbolic name. This must be set if Server is + not set. type: string namespace: description: Namespace specifies the target namespace for the @@ -794,8 +857,9 @@ spec: namespace-scoped resources that have not set a value for .metadata.namespace type: string server: - description: Server specifies the URL of the target cluster and - must be set to the Kubernetes control plane API + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is not + set. type: string type: object ignoreDifferences: @@ -1056,6 +1120,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -1344,6 +1439,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -1785,6 +1911,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -2086,6 +2243,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -2531,6 +2719,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -2849,6 +3068,38 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize + patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -3281,6 +3532,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -3592,6 +3874,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -3793,7 +4106,8 @@ spec: properties: name: description: Name is an alternate way of specifying the - target cluster by its symbolic name + target cluster by its symbolic name. This must be set + if Server is not set. type: string namespace: description: Namespace specifies the target namespace @@ -3802,8 +4116,9 @@ spec: not set a value for .metadata.namespace type: string server: - description: Server specifies the URL of the target cluster - and must be set to the Kubernetes control plane API + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name + is not set. type: string type: object ignoreDifferences: @@ -4045,6 +4360,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -4356,6 +4702,37 @@ spec: description: Namespace sets the namespace that Kustomize adds to all resources type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: description: Replicas is a list of Kustomize Replicas override specifications @@ -4482,4 +4859,4 @@ spec: type: object served: true storage: true - subresources: {} + subresources: {} \ No newline at end of file diff --git a/config/crd/bases/argoproj.io_applicationsets.yaml b/config/crd/bases/argoproj.io_applicationsets.yaml index 72d23d94a..7d207ba66 100644 --- a/config/crd/bases/argoproj.io_applicationsets.yaml +++ b/config/crd/bases/argoproj.io_applicationsets.yaml @@ -258,6 +258,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -438,6 +468,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -777,6 +837,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -957,6 +1047,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1300,6 +1420,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1480,6 +1630,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1803,6 +1983,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -1983,6 +2193,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -2330,6 +2570,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -2510,6 +2780,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -2849,6 +3149,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3029,6 +3359,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3366,12 +3726,42 @@ spec: items: type: string type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3552,6 +3942,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -3875,6 +4295,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -4055,6 +4505,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -4388,6 +4868,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -4568,6 +5078,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5081,6 +5621,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5261,6 +5831,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5553,6 +6153,8 @@ spec: type: string group: type: string + includeSharedProjects: + type: boolean includeSubgroups: type: boolean insecure: @@ -5567,6 +6169,8 @@ spec: - key - secretName type: object + topic: + type: string required: - group type: object @@ -5765,6 +6369,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -5945,6 +6579,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6282,6 +6946,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6462,6 +7156,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6803,12 +7527,42 @@ spec: items: type: string type: array - namePrefix: - type: string - nameSuffix: - type: string - namespace: - type: string + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -6989,6 +7743,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -7328,6 +8112,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -7508,6 +8322,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -7851,6 +8695,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8031,6 +8905,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8354,6 +9258,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8534,6 +9468,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -8867,6 +9831,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -9047,6 +10041,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -9560,6 +10584,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -9740,6 +10794,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10032,6 +11116,8 @@ spec: type: string group: type: string + includeSharedProjects: + type: boolean includeSubgroups: type: boolean insecure: @@ -10046,6 +11132,8 @@ spec: - key - secretName type: object + topic: + type: string required: - group type: object @@ -10244,6 +11332,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10424,6 +11542,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10765,6 +11913,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -10945,6 +12123,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -11275,6 +12483,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -11455,6 +12693,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -11968,6 +13236,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12148,6 +13446,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12440,6 +13768,8 @@ spec: type: string group: type: string + includeSharedProjects: + type: boolean includeSubgroups: type: boolean insecure: @@ -12454,6 +13784,8 @@ spec: - key - secretName type: object + topic: + type: string required: - group type: object @@ -12652,6 +13984,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12832,6 +14194,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -12983,12 +14375,31 @@ spec: items: type: string type: array + ignoreApplicationDifferences: + items: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + name: + type: string + type: object + type: array preservedFields: properties: annotations: items: type: string type: array + labels: + items: + type: string + type: array type: object strategy: properties: @@ -13225,6 +14636,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -13405,6 +14846,36 @@ spec: type: string namespace: type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array replicas: items: properties: @@ -13576,4 +15047,4 @@ spec: served: true storage: true subresources: - status: {} + status: {} \ No newline at end of file diff --git a/config/crd/bases/argoproj.io_appprojects.yaml b/config/crd/bases/argoproj.io_appprojects.yaml index 9fdc4e317..72657ae05 100644 --- a/config/crd/bases/argoproj.io_appprojects.yaml +++ b/config/crd/bases/argoproj.io_appprojects.yaml @@ -88,7 +88,8 @@ spec: properties: name: description: Name is an alternate way of specifying the target - cluster by its symbolic name + cluster by its symbolic name. This must be set if Server is + not set. type: string namespace: description: Namespace specifies the target namespace for the @@ -96,8 +97,9 @@ spec: namespace-scoped resources that have not set a value for .metadata.namespace type: string server: - description: Server specifies the URL of the target cluster - and must be set to the Kubernetes control plane API + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is + not set. type: string type: object type: array diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index d9f21e827..457d0fd9e 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -13,4 +13,4 @@ kind: Kustomization images: - name: controller newName: quay.io/argoprojlabs/argocd-operator - newTag: v0.8.0 + newTag: v0.9.0 diff --git a/controllers/argocd/dex_test.go b/controllers/argocd/dex_test.go index 3f0ca40a2..8051b08d0 100644 --- a/controllers/argocd/dex_test.go +++ b/controllers/argocd/dex_test.go @@ -499,7 +499,7 @@ func TestReconcileArgoCD_reconcileDexDeployment_withUpdate(t *testing.T) { InitContainers: []corev1.Container{ { Name: "copyutil", - Image: "quay.io/argoproj/argocd@sha256:d40da8f5747415eb7f9b5c2d9b645aecd423888cad9b36e4f986bff8ecf0a786", + Image: "quay.io/argoproj/argocd@sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc", Command: []string{ "cp", "-n", diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml new file mode 100644 index 000000000..8d1547d9a --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-controller-manager-metrics-service_v1_service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + control-plane: argocd-operator + name: argocd-operator-controller-manager-metrics-service +spec: + ports: + - name: https + port: 8443 + targetPort: 8080 + selector: + control-plane: argocd-operator +status: + loadBalancer: {} diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-manager-config_v1_configmap.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-manager-config_v1_configmap.yaml new file mode 100644 index 000000000..e04f24437 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-manager-config_v1_configmap.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +data: + controller_manager_config.yaml: | + apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 + kind: ControllerManagerConfig + health: + healthProbeBindAddress: :8081 + metrics: + bindAddress: 127.0.0.1:8080 + webhook: + port: 9443 + leaderElection: + leaderElect: true + resourceName: b674928d.argoproj.io +kind: ConfigMap +metadata: + name: argocd-operator-manager-config diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 000000000..19a68a570 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: argocd-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-webhook-service_v1_service.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-webhook-service_v1_service.yaml new file mode 100644 index 000000000..f5dda7bc9 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator-webhook-service_v1_service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + name: argocd-operator-webhook-service +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: argocd-operator +status: + loadBalancer: {} diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator.v0.9.0.clusterserviceversion.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator.v0.9.0.clusterserviceversion.yaml new file mode 100644 index 000000000..c9f758a34 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argocd-operator.v0.9.0.clusterserviceversion.yaml @@ -0,0 +1,1849 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "AppProject", + "metadata": { + "name": "example" + }, + "spec": null + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "Application", + "metadata": { + "name": "example" + }, + "spec": null + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "ApplicationSet", + "metadata": { + "name": "example" + }, + "spec": null + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "ArgoCD", + "metadata": { + "name": "argocd-sample" + }, + "spec": { + "controller": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "2048Mi" + }, + "requests": { + "cpu": "250m", + "memory": "1024Mi" + } + } + }, + "ha": { + "enabled": false, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "redis": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "repo": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "512Mi" + }, + "requests": { + "cpu": "250m", + "memory": "256Mi" + } + } + }, + "server": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "125m", + "memory": "128Mi" + } + }, + "route": { + "enabled": true + } + }, + "sso": { + "dex": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "provider": "dex" + } + } + }, + { + "apiVersion": "argoproj.io/v1alpha1", + "kind": "ArgoCDExport", + "metadata": { + "name": "argocdexport-sample" + }, + "spec": { + "argocd": "argocd-sample" + } + }, + { + "apiVersion": "argoproj.io/v1beta1", + "kind": "ArgoCD", + "metadata": { + "name": "argocd-sample" + }, + "spec": { + "controller": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "2048Mi" + }, + "requests": { + "cpu": "250m", + "memory": "1024Mi" + } + } + }, + "ha": { + "enabled": false, + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "redis": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "repo": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "512Mi" + }, + "requests": { + "cpu": "250m", + "memory": "256Mi" + } + } + }, + "server": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "125m", + "memory": "128Mi" + } + }, + "route": { + "enabled": true + } + }, + "sso": { + "dex": { + "resources": { + "limits": { + "cpu": "500m", + "memory": "256Mi" + }, + "requests": { + "cpu": "250m", + "memory": "128Mi" + } + } + }, + "provider": "dex" + } + } + } + ] + capabilities: Deep Insights + categories: Integration & Delivery + certified: "false" + description: Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. + operators.operatorframework.io/builder: operator-sdk-v1.10.0+git + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + repository: https://github.com/argoproj-labs/argocd-operator + support: Argo CD + name: argocd-operator.v0.9.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: An Application is a group of Kubernetes resources as defined by + a manifest. + displayName: Application + kind: Application + name: applications.argoproj.io + version: v1alpha1 + - description: An ApplicationSet is a group or set of Application resources. + displayName: ApplicationSet + kind: ApplicationSet + name: applicationsets.argoproj.io + version: v1alpha1 + - description: An AppProject is a logical grouping of Argo CD Applications. + displayName: AppProject + kind: AppProject + name: appprojects.argoproj.io + version: v1alpha1 + - description: ArgoCDExport is the Schema for the argocdexports API + displayName: Argo CDExport + kind: ArgoCDExport + name: argocdexports.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1alpha1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: Argocd is the name of the ArgoCD instance to export. + displayName: ArgoCD + path: argocd + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + displayName: Schedule + path: schedule + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: Storage defines the storage configuration options. + displayName: Storage + path: storage + statusDescriptors: + - description: 'Phase is a simple, high-level summary of where the ArgoCDExport + is in its lifecycle. There are five possible phase values: Pending: The + ArgoCDExport has been accepted by the Kubernetes system, but one or more + of the required resources have not been created. Running: All of the containers + for the ArgoCDExport are still running, or in the process of starting or + restarting. Succeeded: All containers for the ArgoCDExport have terminated + in success, and will not be restarted. Failed: At least one container has + terminated in failure, either exited with non-zero status or was terminated + by the system. Unknown: For some reason the state of the ArgoCDExport could + not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1alpha1 + - description: ArgoCD is the Schema for the argocds API + displayName: Argo CD + kind: ArgoCD + name: argocds.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1alpha1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: ApplicationInstanceLabelKey is the key name where Argo CD injects + the app name as a tracking label. + displayName: Application Instance Label Key' + path: applicationInstanceLabelKey + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: applicationSet.webhookServer.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: applicationSet.webhookServer.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: applicationSet.webhookServer.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ConfigManagementPlugins is used to specify additional config + management plugins. + displayName: Config Management Plugins' + path: configManagementPlugins + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Operation is the number of application operation processors. + displayName: Operation Processor Count' + path: controller.processors.operation + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Status is the number of application status processors. + displayName: Status Processor Count' + path: controller.processors.status + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resources defines the Compute Resources required by the container + for the Application Controller. + displayName: Resource Requirements' + path: controller.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Config is the dex connector configuration. + displayName: Configuration + path: dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: GAAnonymizeUsers toggles user IDs being hashed before sending + to google analytics. + displayName: Google Analytics Anonymize Users' + path: gaAnonymizeUsers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: GATrackingID is the google analytics tracking ID to use. + displayName: Google Analytics Tracking ID' + path: gaTrackingID + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Grafana support globally for ArgoCD. + displayName: Enabled + path: grafana.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: grafana.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Grafana container image. + displayName: Image + path: grafana.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: grafana.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Grafana. + displayName: Resource Requirements' + path: grafana.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: grafana.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Grafana Deployment. + displayName: Size + path: grafana.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Version is the Grafana container image tag. + displayName: Version + path: grafana.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle HA support globally for Argo CD. + displayName: Enabled + path: ha.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: HelpChatText is the text for getting chat help, defaults to "Chat + now!" + displayName: Help Chat Text' + path: helpChatText + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: HelpChatURL is the URL for getting chat help, this will typically + be your Slack channel for support. + displayName: Help Chat URL' + path: helpChatURL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Image is the ArgoCD container image for all ArgoCD components. + displayName: Image + path: image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of an ArgoCDExport from which to import data. + displayName: Name + path: import.name + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: Namespace for the ArgoCDExport, defaults to the same namespace + as the ArgoCD. + displayName: Namespace + path: import.namespace + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: InitialRepositories to configure Argo CD with upon creation of + the cluster. + displayName: Initial Repositories' + path: initialRepositories + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: KustomizeVersions is a listing of configured versions of Kustomize + to be made available within ArgoCD. + displayName: Kustomize Build Options' + path: kustomizeVersions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: OIDCConfig is the OIDC configuration as an alternative to dex. + displayName: OIDC Config' + path: oidcConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Prometheus support globally for ArgoCD. + displayName: Enabled + path: prometheus.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: prometheus.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: prometheus.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: prometheus.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Prometheus StatefulSet. + displayName: Size + path: prometheus.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: DefaultPolicy is the name of the default role which Argo CD will + falls back to, when authorizing API requests (optional). If omitted or empty, + users may be still be able to login, but will see no apps, projects, etc... + displayName: Default Policy' + path: rbac.defaultPolicy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Policy is CSV containing user-defined RBAC policies and role + definitions. Policy rules are in the form: p, subject, resource, action, + object, effect Role definitions and bindings are in the form: g, subject, + inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + displayName: Policy + path: rbac.policy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Scopes controls which OIDC scopes to examine during rbac enforcement + (in addition to `sub` scope). If omitted, defaults to: ''[groups]''.' + displayName: Scopes + path: rbac.scopes + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Redis container image. + displayName: Image + path: redis.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: redis.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Redis container image tag. + displayName: Version + path: redis.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: repo.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: ResourceActions customizes resource action behavior. + displayName: Resource Action Customizations' + path: resourceActions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: 'Deprecated field. Support dropped in v1beta1 version. ResourceCustomizations + customizes resource behavior. Keys are in the form: group/Kind. Please note + that this is being deprecated in favor of ResourceHealthChecks, ResourceIgnoreDifferences, + and ResourceActions.' + displayName: Resource Customizations' + path: resourceCustomizations + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceExclusions is used to completely ignore entire classes + of resource group/kinds. + displayName: Resource Exclusions' + path: resourceExclusions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceHealthChecks customizes resource health check behavior. + displayName: Resource Health Check Customizations' + path: resourceHealthChecks + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceIgnoreDifferences customizes resource ignore difference + behavior. + displayName: Resource Ignore Difference Customizations' + path: resourceIgnoreDifferences + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceTrackingMethod defines how Argo CD should track resources + that it manages + displayName: Resource Tracking Method' + path: resourceTrackingMethod + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle autoscaling support for the Argo CD Server + component. + displayName: Autoscale Enabled' + path: server.autoscale.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: GRPC Host + path: server.grpc.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Ingress defines the desired state for the Argo CD Server GRPC + Ingress. + displayName: GRPC Ingress Enabled' + path: server.grpc.ingress + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.grpc.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: server.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Insecure toggles the insecure flag. + displayName: Insecure + path: server.insecure + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for the Argo CD server component. + displayName: Resource Requirements' + path: server.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: server.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Type is the ServiceType to use for the Service resource. + displayName: Service Type' + path: server.service.type + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Config is the dex connector configuration. + displayName: Configuration + path: sso.dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: sso.dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: sso.dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: sso.dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: sso.dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: StatusBadgeEnabled toggles application status badge feature. + displayName: Status Badge Enabled' + path: statusBadgeEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: UsersAnonymousEnabled toggles anonymous user access. The anonymous + users get default role permissions specified argocd-rbac-cm. + displayName: Anonymous Users Enabled' + path: usersAnonymousEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Version is the tag to use with the ArgoCD container image for + all ArgoCD components. + displayName: Version + path: version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + statusDescriptors: + - description: 'ApplicationController is a simple, high-level summary of where + the Argo CD application controller component is in its lifecycle. There + are four possible ApplicationController values: Pending: The Argo CD application + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD application controller component are in + a Ready state. Failed: At least one of the Argo CD application controller + component Pods had a failure. Unknown: The state of the Argo CD application + controller component could not be obtained.' + displayName: ApplicationController + path: applicationController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'ApplicationSetController is a simple, high-level summary of + where the Argo CD applicationSet controller component is in its lifecycle. + There are four possible ApplicationSetController values: Pending: The Argo + CD applicationSet controller component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD applicationSet controller + component are in a Ready state. Failed: At least one of the Argo CD applicationSet + controller component Pods had a failure. Unknown: The state of the Argo + CD applicationSet controller component could not be obtained.' + displayName: ApplicationSetController + path: applicationSetController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'NotificationsController is a simple, high-level summary of where + the Argo CD notifications controller component is in its lifecycle. There + are four possible NotificationsController values: Pending: The Argo CD notifications + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD notifications controller component are + in a Ready state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD notifications + controller component could not be obtained.' + displayName: NotificationsController + path: notificationsController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Phase is a simple, high-level summary of where the ArgoCD is + in its lifecycle. There are four possible phase values: Pending: The ArgoCD + has been accepted by the Kubernetes system, but one or more of the required + resources have not been created. Available: All of the resources for the + ArgoCD are ready. Failed: At least one resource has experienced a failure. + Unknown: The state of the ArgoCD phase could not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Redis is a simple, high-level summary of where the Argo CD Redis + component is in its lifecycle. There are four possible redis values: Pending: + The Argo CD Redis component has been accepted by the Kubernetes system, + but one or more of the required resources have not been created. Running: + All of the required Pods for the Argo CD Redis component are in a Ready + state. Failed: At least one of the Argo CD Redis component Pods had a failure. + Unknown: The state of the Argo CD Redis component could not be obtained.' + displayName: Redis + path: redis + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Repo is a simple, high-level summary of where the Argo CD Repo + component is in its lifecycle. There are four possible repo values: Pending: + The Argo CD Repo component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Repo component are in a Ready state. + Failed: At least one of the Argo CD Repo component Pods had a failure. + Unknown: The state of the Argo CD Repo component could not be obtained.' + displayName: Repo + path: repo + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Server is a simple, high-level summary of where the Argo CD + server component is in its lifecycle. There are four possible server values: + Pending: The Argo CD server component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD server component are in + a Ready state. Failed: At least one of the Argo CD server component Pods + had a failure. Unknown: The state of the Argo CD server component could + not be obtained.' + displayName: Server + path: server + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) + component is in its lifecycle. There are four possible sso values: Pending: + The Argo CD SSO component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD SSO component are in a Ready state. + Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: + The state of the Argo CD SSO component could not be obtained.' + displayName: SSO + path: sso + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1alpha1 + - description: ArgoCD is the Schema for the argocds API + displayName: Argo CD + kind: ArgoCD + name: argocds.argoproj.io + resources: + - kind: ArgoCD + name: "" + version: v1beta1 + - kind: ArgoCDExport + name: "" + version: v1alpha1 + - kind: ConfigMap + name: "" + version: v1 + - kind: CronJob + name: "" + version: v1 + - kind: Deployment + name: "" + version: v1 + - kind: Ingress + name: "" + version: v1 + - kind: Job + name: "" + version: v1 + - kind: PersistentVolumeClaim + name: "" + version: v1 + - kind: Pod + name: "" + version: v1 + - kind: Prometheus + name: "" + version: v1 + - kind: ReplicaSet + name: "" + version: v1 + - kind: Route + name: "" + version: v1 + - kind: Secret + name: "" + version: v1 + - kind: Service + name: "" + version: v1 + - kind: ServiceMonitor + name: "" + version: v1 + - kind: StatefulSet + name: "" + version: v1 + specDescriptors: + - description: ApplicationInstanceLabelKey is the key name where Argo CD injects + the app name as a tracking label. + displayName: Application Instance Label Key' + path: applicationInstanceLabelKey + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: applicationSet.webhookServer.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: applicationSet.webhookServer.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: applicationSet.webhookServer.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: ConfigManagementPlugins is used to specify additional config + management plugins. + displayName: Config Management Plugins' + path: configManagementPlugins + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Operation is the number of application operation processors. + displayName: Operation Processor Count' + path: controller.processors.operation + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Status is the number of application status processors. + displayName: Status Processor Count' + path: controller.processors.status + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:number + - description: Resources defines the Compute Resources required by the container + for the Application Controller. + displayName: Resource Requirements' + path: controller.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Controller + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: GAAnonymizeUsers toggles user IDs being hashed before sending + to google analytics. + displayName: Google Analytics Anonymize Users' + path: gaAnonymizeUsers + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: GATrackingID is the google analytics tracking ID to use. + displayName: Google Analytics Tracking ID' + path: gaTrackingID + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Grafana support globally for ArgoCD. + displayName: Enabled + path: grafana.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: grafana.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Grafana container image. + displayName: Image + path: grafana.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: grafana.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Grafana. + displayName: Resource Requirements' + path: grafana.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: grafana.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Grafana Deployment. + displayName: Size + path: grafana.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Version is the Grafana container image tag. + displayName: Version + path: grafana.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle HA support globally for Argo CD. + displayName: Enabled + path: ha.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:HA + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: HelpChatText is the text for getting chat help, defaults to "Chat + now!" + displayName: Help Chat Text' + path: helpChatText + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: HelpChatURL is the URL for getting chat help, this will typically + be your Slack channel for support. + displayName: Help Chat URL' + path: helpChatURL + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Image is the ArgoCD container image for all ArgoCD components. + displayName: Image + path: image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + - description: Name of an ArgoCDExport from which to import data. + displayName: Name + path: import.name + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: Namespace for the ArgoCDExport, defaults to the same namespace + as the ArgoCD. + displayName: Namespace + path: import.namespace + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Import + - urn:alm:descriptor:com.tectonic.ui:text + - description: InitialRepositories to configure Argo CD with upon creation of + the cluster. + displayName: Initial Repositories' + path: initialRepositories + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: KustomizeVersions is a listing of configured versions of Kustomize + to be made available within ArgoCD. + displayName: Kustomize Build Options' + path: kustomizeVersions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: OIDCConfig is the OIDC configuration as an alternative to dex. + displayName: OIDC Config' + path: oidcConfig + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle Prometheus support globally for ArgoCD. + displayName: Enabled + path: prometheus.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: prometheus.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: prometheus.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: prometheus.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Size is the replica count for the Prometheus StatefulSet. + displayName: Size + path: prometheus.size + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:podCount + - description: DefaultPolicy is the name of the default role which Argo CD will + falls back to, when authorizing API requests (optional). If omitted or empty, + users may be still be able to login, but will see no apps, projects, etc... + displayName: Default Policy' + path: rbac.defaultPolicy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Policy is CSV containing user-defined RBAC policies and role + definitions. Policy rules are in the form: p, subject, resource, action, + object, effect Role definitions and bindings are in the form: g, subject, + inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + displayName: Policy + path: rbac.policy + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Scopes controls which OIDC scopes to examine during rbac enforcement + (in addition to `sub` scope). If omitted, defaults to: ''[groups]''.' + displayName: Scopes + path: rbac.scopes + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:RBAC + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Redis container image. + displayName: Image + path: redis.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: redis.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Redis container image tag. + displayName: Version + path: redis.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Redis + - urn:alm:descriptor:com.tectonic.ui:text + - description: Resources defines the Compute Resources required by the container + for Redis. + displayName: Resource Requirements' + path: repo.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Repo + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: ResourceActions customizes resource action behavior. + displayName: Resource Action Customizations' + path: resourceActions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceExclusions is used to completely ignore entire classes + of resource group/kinds. + displayName: Resource Exclusions' + path: resourceExclusions + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceHealthChecks customizes resource health check behavior. + displayName: Resource Health Check Customizations' + path: resourceHealthChecks + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceIgnoreDifferences customizes resource ignore difference + behavior. + displayName: Resource Ignore Difference Customizations' + path: resourceIgnoreDifferences + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: ResourceTrackingMethod defines how Argo CD should track resources + that it manages + displayName: Resource Tracking Method' + path: resourceTrackingMethod + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Enabled will toggle autoscaling support for the Argo CD Server + component. + displayName: Autoscale Enabled' + path: server.autoscale.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: GRPC Host + path: server.grpc.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Ingress defines the desired state for the Argo CD Server GRPC + Ingress. + displayName: GRPC Ingress Enabled' + path: server.grpc.ingress + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.grpc.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Host is the hostname to use for Ingress/Route resources. + displayName: Host + path: server.host + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Enabled will toggle the creation of the Ingress. + displayName: Ingress Enabled' + path: server.ingress.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Insecure toggles the insecure flag. + displayName: Insecure + path: server.insecure + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for the Argo CD server component. + displayName: Resource Requirements' + path: server.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Enabled will toggle the creation of the OpenShift Route. + displayName: Route Enabled' + path: server.route.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Grafana + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Prometheus + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Type is the ServiceType to use for the Service resource. + displayName: Service Type' + path: server.service.type + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Server + - urn:alm:descriptor:com.tectonic.ui:text + - description: Config is the dex connector configuration. + displayName: Configuration + path: sso.dex.config + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: Image is the Dex container image. + displayName: Image + path: sso.dex.image + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: OpenShiftOAuth enables OpenShift OAuth authentication for the + Dex server. + displayName: OpenShift OAuth Enabled' + path: sso.dex.openShiftOAuth + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Resources defines the Compute Resources required by the container + for Dex. + displayName: Resource Requirements' + path: sso.dex.resources + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:resourceRequirements + - description: Version is the Dex container image tag. + displayName: Version + path: sso.dex.version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:Dex + - urn:alm:descriptor:com.tectonic.ui:text + - description: StatusBadgeEnabled toggles application status badge feature. + displayName: Status Badge Enabled' + path: statusBadgeEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: UsersAnonymousEnabled toggles anonymous user access. The anonymous + users get default role permissions specified argocd-rbac-cm. + displayName: Anonymous Users Enabled' + path: usersAnonymousEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: Version is the tag to use with the ArgoCD container image for + all ArgoCD components. + displayName: Version + path: version + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:fieldGroup:ArgoCD + - urn:alm:descriptor:com.tectonic.ui:text + statusDescriptors: + - description: 'ApplicationController is a simple, high-level summary of where + the Argo CD application controller component is in its lifecycle. There + are four possible ApplicationController values: Pending: The Argo CD application + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD application controller component are in + a Ready state. Failed: At least one of the Argo CD application controller + component Pods had a failure. Unknown: The state of the Argo CD application + controller component could not be obtained.' + displayName: ApplicationController + path: applicationController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'ApplicationSetController is a simple, high-level summary of + where the Argo CD applicationSet controller component is in its lifecycle. + There are four possible ApplicationSetController values: Pending: The Argo + CD applicationSet controller component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD applicationSet controller + component are in a Ready state. Failed: At least one of the Argo CD applicationSet + controller component Pods had a failure. Unknown: The state of the Argo + CD applicationSet controller component could not be obtained.' + displayName: ApplicationSetController + path: applicationSetController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'NotificationsController is a simple, high-level summary of where + the Argo CD notifications controller component is in its lifecycle. There + are four possible NotificationsController values: Pending: The Argo CD notifications + controller component has been accepted by the Kubernetes system, but one + or more of the required resources have not been created. Running: All of + the required Pods for the Argo CD notifications controller component are + in a Ready state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD notifications + controller component could not be obtained.' + displayName: NotificationsController + path: notificationsController + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Phase is a simple, high-level summary of where the ArgoCD is + in its lifecycle. There are four possible phase values: Pending: The ArgoCD + has been accepted by the Kubernetes system, but one or more of the required + resources have not been created. Available: All of the resources for the + ArgoCD are ready. Failed: At least one resource has experienced a failure. + Unknown: The state of the ArgoCD phase could not be obtained.' + displayName: Phase + path: phase + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Redis is a simple, high-level summary of where the Argo CD Redis + component is in its lifecycle. There are four possible redis values: Pending: + The Argo CD Redis component has been accepted by the Kubernetes system, + but one or more of the required resources have not been created. Running: + All of the required Pods for the Argo CD Redis component are in a Ready + state. Failed: At least one of the Argo CD Redis component Pods had a failure. + Unknown: The state of the Argo CD Redis component could not be obtained.' + displayName: Redis + path: redis + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Repo is a simple, high-level summary of where the Argo CD Repo + component is in its lifecycle. There are four possible repo values: Pending: + The Argo CD Repo component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD Repo component are in a Ready state. + Failed: At least one of the Argo CD Repo component Pods had a failure. + Unknown: The state of the Argo CD Repo component could not be obtained.' + displayName: Repo + path: repo + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'Server is a simple, high-level summary of where the Argo CD + server component is in its lifecycle. There are four possible server values: + Pending: The Argo CD server component has been accepted by the Kubernetes + system, but one or more of the required resources have not been created. + Running: All of the required Pods for the Argo CD server component are in + a Ready state. Failed: At least one of the Argo CD server component Pods + had a failure. Unknown: The state of the Argo CD server component could + not be obtained.' + displayName: Server + path: server + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + - description: 'SSO is a simple, high-level summary of where the Argo CD SSO(Dex/Keycloak) + component is in its lifecycle. There are four possible sso values: Pending: + The Argo CD SSO component has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: All + of the required Pods for the Argo CD SSO component are in a Ready state. + Failed: At least one of the Argo CD SSO component Pods had a failure. Unknown: + The state of the Argo CD SSO component could not be obtained.' + displayName: SSO + path: sso + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:text + version: v1beta1 + description: | + ## Overview + + The Argo CD Operator manages the full lifecycle for [Argo CD](https://argoproj.github.io/argo-cd/) and it's + components. The operator's goal is to automate the tasks required when operating an Argo CD cluster. + + Beyond installation, the operator helps to automate the process of upgrading, backing up and restoring as needed and + remove the human as much as possible. In addition, the operator aims to provide deep insights into the Argo CD + environment by configuring Prometheus and Grafana to aggregate, visualize and expose the metrics already exported by + Argo CD. + + The operator aims to provide the following, and is a work in progress. + + * Easy configuration and installation of the Argo CD components with sane defaults to get up and running quickly. + * Provide seamless upgrades to the Argo CD components. + * Ability to back up and restore an Argo CD cluster from a point in time or on a recurring schedule. + * Aggregate and expose the metrics for Argo CD and the operator itself using Prometheus and Grafana. + * Autoscale the Argo CD components as necessary to handle variability in demand. + + ## Usage + + Deploy a basic Argo CD cluster by creating a new ArgoCD resource in the namespace where the operator is installed. + + ``` + apiVersion: argoproj.io/v1alpha1 + kind: ArgoCD + metadata: + name: example-argocd + spec: {} + ``` + + ## Backup + + Backup the cluster above by creating a new ArgoCDExport resource in the namespace where the operator is installed. + + ``` + apiVersion: argoproj.io/v1alpha1 + kind: ArgoCDExport + metadata: + name: example-argocdexport + spec: + argocd: example-argocd + ``` + + See the [documentation](https://argocd-operator.readthedocs.io) and examples on + [github](https://github.com/argoproj-labs/argocd-operator) for more information. + displayName: Argo CD + icon: + - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+Cjxzdmcgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDIzIDMwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MjsiPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMSwwLDAsMSwtOS4yLC03KSI+CiAgICAgICAgPGc+CiAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2LDI3LjdDMTYsMjcuNyAxNS44LDI4LjMgMTUuNSwyOC42QzE1LjMsMjguOCAxNS4xLDI4LjkgMTQuOCwyOC45QzE0LjEsMjkuMSAxMy4zLDI5LjIgMTMuMywyOS4yQzEzLjMsMjkuMiAxNCwyOS4zIDE0LjgsMjkuNEMxNS4xLDI5LjQgMTUuMSwyOS40IDE1LjMsMjkuNUMxNS44LDI5LjUgMTYsMjkuMiAxNiwyOS4yTDE2LDI3LjdaIiBzdHlsZT0iZmlsbDpyZ2IoMjMzLDEwMSw3NSk7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuMiwyNy43QzI1LjIsMjcuNyAyNS40LDI4LjMgMjUuNywyOC42QzI1LjksMjguOCAyNi4xLDI4LjkgMjYuNCwyOC45QzI3LjEsMjkuMSAyNy45LDI5LjIgMjcuOSwyOS4yQzI3LjksMjkuMiAyNy4yLDI5LjMgMjYuMywyOS40QzI2LDI5LjQgMjYsMjkuNCAyNS44LDI5LjVDMjUuMiwyOS41IDI1LjEsMjkuMiAyNS4xLDI5LjJMMjUuMiwyNy43WiIgc3R5bGU9ImZpbGw6cmdiKDIzMywxMDEsNzUpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMjAuNyIgY3k9IjE3LjgiIHI9IjEwLjgiIHN0eWxlPSJmaWxsOnJnYigxODIsMjA3LDIzNCk7Ii8+CiAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIyMC43IiBjeT0iMTcuOCIgcj0iMTAuNCIgc3R5bGU9ImZpbGw6cmdiKDIzMCwyNDUsMjQ4KTsiLz4KICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9IjIwLjciIGN5PSIxOCIgcj0iOC41IiBzdHlsZT0iZmlsbDpyZ2IoMjA4LDIzMiwyNDApOyIvPgogICAgICAgICAgICAgICAgPGcgaWQ9IkJvZHlfMV8iPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNS43LDIyQzE1LjcsMjIgMTYuNCwzMy4zIDE2LjQsMzMuNUMxNi40LDMzLjYgMTYuNSwzMy44IDE2LDM0QzE1LjUsMzQuMiAxMy45LDM0LjYgMTMuOSwzNC42TDE2LjMsMzQuNkMxNy40LDM0LjYgMTcuNCwzMy43IDE3LjQsMzMuNUMxNy40LDMzLjMgMTcuNywyOSAxNy43LDI5QzE3LjcsMjkgMTcuOCwzNC4xIDE3LjgsMzQuM0MxNy44LDM0LjUgMTcuNywzNC44IDE3LDM1QzE2LjUsMzUuMSAxNSwzNS40IDE1LDM1LjRMMTcuMywzNS40QzE4LjcsMzUuNCAxOC43LDM0LjUgMTguNywzNC41TDE5LDMwQzE5LDMwIDE5LjEsMzQuNSAxOS4xLDM1QzE5LjEsMzUuNCAxOC44LDM1LjcgMTcuNywzNS45QzE3LDM2LjEgMTYuMSwzNi4zIDE2LjEsMzYuM0wxOC43LDM2LjNDMjAsMzYuMiAyMC4yLDM1LjMgMjAuMiwzNS4zTDIyLjQsMjQuMUwxNS43LDIyWiIgc3R5bGU9ImZpbGw6cmdiKDIzOCwxMjEsNzUpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yNS43LDIyQzI1LjcsMjIgMjUsMzMuMyAyNSwzMy41QzI1LDMzLjYgMjQuOSwzMy44IDI1LjQsMzRDMjUuOSwzNC4yIDI3LjUsMzQuNiAyNy41LDM0LjZMMjUuMSwzNC42QzI0LDM0LjYgMjQsMzMuNyAyNCwzMy41QzI0LDMzLjMgMjMuNywyOSAyMy43LDI5QzIzLjcsMjkgMjMuNiwzNC4xIDIzLjYsMzQuM0MyMy42LDM0LjUgMjMuNywzNC44IDI0LjQsMzVDMjQuOSwzNS4xIDI2LjQsMzUuNCAyNi40LDM1LjRMMjQuMSwzNS40QzIyLjcsMzUuNCAyMi43LDM0LjUgMjIuNywzNC41TDIyLjQsMzBDMjIuNCwzMCAyMi4zLDM0LjUgMjIuMywzNUMyMi4zLDM1LjQgMjIuNiwzNS43IDIzLjcsMzUuOUMyNC40LDM2LjEgMjUuMywzNi4zIDI1LjMsMzYuM0wyMi43LDM2LjNDMjEuNCwzNi4yIDIxLjIsMzUuMyAyMS4yLDM1LjNMMTksMjQuMUwyNS43LDIyWiIgc3R5bGU9ImZpbGw6cmdiKDIzOCwxMjEsNzUpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yNS44LDE2LjVDMjUuOCwxOS4zIDIzLjUsMjEuNSAyMC44LDIxLjVDMTguMSwyMS41IDE1LjgsMTkuMiAxNS44LDE2LjVDMTUuOCwxMy44IDE4LjEsMTEuNSAyMC44LDExLjVDMjMuNSwxMS41IDI1LjgsMTMuNyAyNS44LDE2LjVaIiBzdHlsZT0iZmlsbDpyZ2IoMjM4LDEyMSw3NSk7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICAgICAgPGNsaXBQYXRoIGlkPSJfY2xpcDEiPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuOCwxNi4zTDI1LjIsMzBMMTYuMiwzMEwxNS43LDE2LjMiLz4KICAgICAgICAgICAgICAgICAgICA8L2NsaXBQYXRoPgogICAgICAgICAgICAgICAgICAgIDxnIGNsaXAtcGF0aD0idXJsKCNfY2xpcDEpIj4KICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMjAuOCIgY3k9IjE5LjIiIHI9IjguOSIgc3R5bGU9ImZpbGw6cmdiKDIzOCwxMjEsNzUpOyIvPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuNSwyMkMyNS41LDIyIDI2LjEsMTYuNyAyNS4zLDE0LjdDMjMuOCwxMS4yIDIwLjMsMTEuNSAyMC4zLDExLjVDMjAuMywxMS41IDIyLjMsMTIuMyAyMi40LDE1LjNDMjIuNSwxNy40IDIyLjQsMjAuNSAyMi40LDIwLjVMMjUuNSwyMloiIHN0eWxlPSJmaWxsOnJnYigyMjcsNzgsNTkpO2ZpbGwtb3BhY2l0eTowLjIyO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPGcgaWQ9IkZhY2VfMV8iPgogICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9IjE4LjciIGN5PSIxMy44IiByPSIwLjciIHN0eWxlPSJmaWxsOnJnYigyNTEsMjIzLDE5NSk7ZmlsbC1vcGFjaXR5OjAuNTsiLz4KICAgICAgICAgICAgICAgICAgICA8Zz4KICAgICAgICAgICAgICAgICAgICAgICAgPGc+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjIuNSwyNEMyMi41LDI1LjcgMjEuNywyNi44IDIwLjcsMjYuOEMxOS43LDI2LjggMTguOSwyNS41IDE4LjksMjMuOEMxOC45LDIzLjggMTkuNywyNS40IDIwLjgsMjUuNEMyMS45LDI1LjQgMjIuNSwyNCAyMi41LDI0WiIgc3R5bGU9ImZpbGw6cmdiKDEsMSwxKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMi41LDI0QzIyLjUsMjUuMSAyMS43LDI1LjcgMjAuNywyNS43QzE5LjcsMjUuNyAxOSwyNC45IDE5LDIzLjlDMTksMjMuOSAxOS44LDI0LjkgMjAuOSwyNC45QzIyLDI0LjkgMjIuNSwyNCAyMi41LDI0WiIgc3R5bGU9ImZpbGw6d2hpdGU7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgPGc+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Zz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Zz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMjQuMiIgY3k9IjE5LjMiIHI9IjMuMSIgc3R5bGU9ImZpbGw6cmdiKDIzMywxMDEsNzUpOyIvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIxNy4yIiBjeT0iMTkuMyIgcj0iMy4xIiBzdHlsZT0iZmlsbDpyZ2IoMjMzLDEwMSw3NSk7Ii8+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIyNC4yIiBjeT0iMTkuMyIgcj0iMi40IiBzdHlsZT0iZmlsbDp3aGl0ZTsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMTciIGN5PSIxOS4zIiByPSIyLjQiIHN0eWxlPSJmaWxsOndoaXRlOyIvPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9IjE3IiBjeT0iMTkiIHI9IjAuNyIgc3R5bGU9ImZpbGw6cmdiKDEsMSwxKTsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PSIyNC4yIiBjeT0iMTkiIHI9IjAuNyIgc3R5bGU9ImZpbGw6cmdiKDEsMSwxKTsiLz4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik05LjcsMjAuNUM5LjQsMjAuNSA5LjIsMjAuMyA5LjIsMjBMOS4yLDE2QzkuMiwxNS43IDkuNCwxNS41IDkuNywxNS41QzEwLDE1LjUgMTAuMiwxNS43IDEwLjIsMTZMMTAuMiwyMEMxMC4yLDIwLjMgMTAsMjAuNSA5LjcsMjAuNVoiIHN0eWxlPSJmaWxsOnJnYigxODIsMjA3LDIzNCk7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMzEuNSwyMC41QzMxLjIsMjAuNSAzMSwyMC4zIDMxLDIwTDMxLDE2QzMxLDE1LjcgMzEuMiwxNS41IDMxLjUsMTUuNUMzMS44LDE1LjUgMzIsMTUuNyAzMiwxNkwzMiwyMEMzMiwyMC4zIDMxLjgsMjAuNSAzMS41LDIwLjVaIiBzdHlsZT0iZmlsbDpyZ2IoMTgyLDIwNywyMzQpO2ZpbGwtcnVsZTpub256ZXJvOyIvPgogICAgICAgICAgICAgICAgPGNpcmNsZSBjeD0iMTcuMyIgY3k9IjkuOCIgcj0iMC41IiBzdHlsZT0iZmlsbDp3aGl0ZTsiLz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMy43LDIzLjNDMTMuNiwyMy4zIDEzLjUsMjMuMyAxMy40LDIzLjJDMTIuMiwyMS43IDExLjYsMTkuOCAxMS42LDE3LjlDMTEuNiwxNi4zIDEyLDE0LjggMTIuOCwxMy40QzEzLjYsMTIuMSAxNC43LDExIDE2LDEwLjJDMTYuMiwxMC4xIDE2LjQsMTAuMiAxNi41LDEwLjNDMTYuNiwxMC41IDE2LjUsMTAuNyAxNi40LDEwLjhDMTMuOSwxMi4yIDEyLjMsMTQuOSAxMi4zLDE3LjhDMTIuMywxOS42IDEyLjksMjEuMyAxNCwyMi43QzE0LjEsMjIuOCAxNC4xLDIzLjEgMTMuOSwyMy4yQzEzLjgsMjMuMyAxMy44LDIzLjMgMTMuNywyMy4zWiIgc3R5bGU9ImZpbGw6d2hpdGU7ZmlsbC1ydWxlOm5vbnplcm87Ii8+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjUuMiwyOEwyNS4yLDI3LjJDMjMuOCwyOCAyMi4zLDI4LjggMjAuNSwyOC44QzE4LjUsMjguOCAxNy4yLDI3LjkgMTUuOSwyNy4yTDE2LDI4QzE2LDI4IDE3LjUsMjkuNiAyMC42LDI5LjZDMjMuNSwyOS41IDI1LjIsMjggMjUuMiwyOFoiIHN0eWxlPSJmaWxsOnJnYigyMzMsMTAxLDc1KTtmaWxsLW9wYWNpdHk6MC4yNTtmaWxsLXJ1bGU6bm9uemVybzsiLz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg== + mediatype: image/svg+xml + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - events + - namespaces + - persistentvolumeclaims + - pods + - secrets + - serviceaccounts + - services + - services/finalizers + verbs: + - '*' + - apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - get + - apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - '*' + - apiGroups: + - apps + resourceNames: + - argocd-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - apps.openshift.io + resources: + - deploymentconfigs + verbs: + - '*' + - apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - '*' + - apiGroups: + - argoproj.io + resources: + - argocdexports + - argocdexports/finalizers + - argocdexports/status + verbs: + - '*' + - apiGroups: + - argoproj.io + resources: + - argocds + - argocds/finalizers + - argocds/status + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - '*' + - apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - '*' + - apiGroups: + - config.openshift.io + resources: + - clusterversions + verbs: + - get + - list + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - prometheuses + - prometheusrules + - servicemonitors + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - '*' + - apiGroups: + - oauth.openshift.io + resources: + - oauthclients + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - '*' + - apiGroups: + - template.openshift.io + resources: + - templateconfigs + - templateinstances + - templates + verbs: + - '*' + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: argocd-operator-controller-manager + deployments: + - name: argocd-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + control-plane: argocd-operator + strategy: {} + template: + metadata: + labels: + control-plane: argocd-operator + spec: + containers: + - args: + - --leader-elect + command: + - /manager + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: ENABLE_CONVERSION_WEBHOOK + value: "true" + image: quay.io/argoprojlabs/argocd-operator:v0.9.0 + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + securityContext: + runAsNonRoot: true + serviceAccountName: argocd-operator-controller-manager + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: argocd-operator-controller-manager + strategy: deployment + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - gitops + - kubernetes + links: + - name: Argo CD Project + url: https://argoproj.github.io/argo-cd/ + - name: Operator Documentation + url: https://argocd-operator.readthedocs.io + - name: Operator Source Code + url: https://github.com/argoproj-labs/argocd-operator + maintainers: + - email: aveerama@redhat.com + name: Abhishek Veeramalla + maturity: alpha + provider: + name: Argo CD Community + replaces: argocd-operator.v0.7.0 + version: 0.9.0 + webhookdefinitions: + - admissionReviewVersions: + - v1alpha1 + - v1beta1 + containerPort: 443 + conversionCRDs: + - argocds.argoproj.io + deploymentName: argocd-operator-controller-manager + generateName: cargocds.kb.io + sideEffects: None + targetPort: 9443 + type: ConversionWebhook + webhookPath: /convert diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applications.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applications.yaml new file mode 100644 index 000000000..054c1f6d3 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applications.yaml @@ -0,0 +1,4869 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: applications.argoproj.io + app.kubernetes.io/part-of: argocd + name: applications.argoproj.io +spec: + group: argoproj.io + names: + kind: Application + listKind: ApplicationList + plural: applications + shortNames: + - app + - apps + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.sync.status + name: Sync Status + type: string + - jsonPath: .status.health.status + name: Health Status + type: string + - jsonPath: .status.sync.revision + name: Revision + priority: 10 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Application is a definition of Application resource. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + operation: + description: Operation contains information about a requested or running + operation + properties: + info: + description: Info is a list of informational items for this operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent retries + of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default unit + is seconds, but could also be a duration (e.g. "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time allowed + for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + dryRun: + description: DryRun specifies to perform a `kubectl apply --dry-run` + without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides sync + source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from the cluster + that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall be part + of the sync + items: + description: SyncOperationResource contains resources to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: Revision is the revision (Git) or chart version (Helm) + which to sync the application to If omitted, will use the revision + specified in app spec. + type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array + source: + description: Source overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by + not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources for + Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be + commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. + properties: + destination: + description: Destination is a reference to the target Kubernetes server + and namespace + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is not + set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison + items: + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted managers. + Fields mutated by those managers will take precedence over + the desired state defined in the SCM and won't be displayed + in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: Project is a reference to the project this application + belongs to. The empty string means that application belongs to the + 'default' project. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit limits the number of items kept + in the application's revision history, which is used for informational + purposes as well as for rollbacks to previous versions. This should + only be changed in exceptional circumstances. Setting to zero will + store no history. This will reduce storage used. Increasing will + increase the space used to store the history, so we do not recommend + increasing it. Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether to + apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize adds + to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be passed + to helm template, defined as a map. This takes precedence + over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas override + specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifies whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usually an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + controllerNamespace: + description: ControllerNamespace indicates the namespace in which + the application controller is located + type: string + health: + description: Health contains information about the application's current + health status + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory + format: int64 + type: integer + revision: + description: Revision holds the revision the sync was performed + against + type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array + source: + description: Source is a reference to the application source + used for the sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. ValuesObject + takes precedence over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to be + passed to helm template, defined as a map. This takes + precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - deployedAt + - id + type: object + type: array + observedAt: + description: 'ObservedAt indicates when the application state was + updated without querying latest git state Deprecated: controller + no longer updates ObservedAt field' + format: date-time + type: string + operationState: + description: OperationState contains information about any ongoing + operations, such as a sync + properties: + finishedAt: + description: FinishedAt contains time of operation completion + format: date-time + type: string + message: + description: Message holds any pertinent messages when attempting + to perform operation (typically errors). + type: string + operation: + description: Operation is the original requested operation + properties: + info: + description: Info is a list of informational items for this + operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was + initiated automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who + started operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync + fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base + duration after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of + time allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for + retrying a failed sync. If set to 0, no retries will + be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + dryRun: + description: DryRun specifies to perform a `kubectl apply + --dry-run` without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides + sync source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from + the cluster that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall + be part of the sync + items: + description: SyncOperationResource contains resources + to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: Revision is the revision (Git) or chart version + (Helm) which to sync the application to If omitted, + will use the revision specified in app spec. + type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array + source: + description: Source overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to + Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles do + not exist locally by not appending them to helm + template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over + Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a + map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of + Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in + the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block. ValuesObject takes precedence + over Values, so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as + a map. This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution + for annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that + Kustomize adds to all resources + type: string + patches: + description: Patches is a list of Kustomize + patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize + Replicas override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, + e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the + sync + properties: + apply: + description: Apply will perform a `kubectl apply` + to perform the sync. + properties: + force: + description: Force indicates whether or not to + supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, + when PATCH encounters conflict and has retried + for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources + to perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to + supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, + when PATCH encounters conflict and has retried + for 5 times. + type: boolean + type: object + type: object + type: object + type: object + phase: + description: Phase is the current phase of the operation + type: string + retryCount: + description: RetryCount contains time of operation retries + format: int64 + type: integer + startedAt: + description: StartedAt contains time of operation start + format: date-time + type: string + syncResult: + description: SyncResult is the result of a Sync operation + properties: + managedNamespaceMetadata: + description: ManagedNamespaceMetadata contains the current + sync state of managed namespace metadata + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + resources: + description: Resources contains a list of sync result items + for each individual resource in a sync operation + items: + description: ResourceResult holds the operation result details + of a specific resource + properties: + group: + description: Group specifies the API group of the resource + type: string + hookPhase: + description: HookPhase contains the state of any operation + associated with this resource OR hook This can also + contain values for non-hook resources. + type: string + hookType: + description: HookType specifies the type of the hook. + Empty for non-hook resources + type: string + kind: + description: Kind specifies the API kind of the resource + type: string + message: + description: Message contains an informational or error + message for the last sync OR operation + type: string + name: + description: Name specifies the name of the resource + type: string + namespace: + description: Namespace specifies the target namespace + of the resource + type: string + status: + description: Status holds the final result of the sync. + Will be empty if the resources is yet to be applied/pruned + and is always zero-value for hooks + type: string + syncPhase: + description: SyncPhase indicates the particular phase + of the sync that this result was acquired in + type: string + version: + description: Version specifies the API version of the + resource + type: string + required: + - group + - kind + - name + - namespace + - version + type: object + type: array + revision: + description: Revision holds the revision this sync operation + was performed to + type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array + source: + description: Source records the application source information + of the sync, used for comparing auto-sync + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - revision + type: object + required: + - operation + - phase + - startedAt + type: object + reconciledAt: + description: ReconciledAt indicates when the application state was + reconciled using the latest git version + format: date-time + type: string + resourceHealthSource: + description: 'ResourceHealthSource indicates where the resource health + status is stored: inline if not set or appTree' + type: string + resources: + description: Resources is a list of Kubernetes resources managed by + this application + items: + description: 'ResourceStatus holds the current sync and health status + of a resource TODO: describe members of this type' + properties: + group: + type: string + health: + description: HealthStatus contains information about the currently + observed health state of an application or resource + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application + or resource + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresPruning: + type: boolean + status: + description: SyncStatusCode is a type which represents possible + comparison results + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + sourceType: + description: SourceType specifies the type of this application + type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array + summary: + description: Summary contains a list of URLs and container images + used by this application + properties: + externalURLs: + description: ExternalURLs holds all external URLs of application + child resources. + items: + type: string + type: array + images: + description: Images holds all images of application child resources. + items: + type: string + type: array + type: object + sync: + description: Sync contains information about the application's current + sync status + properties: + comparedTo: + description: ComparedTo contains information about what has been + compared + properties: + destination: + description: Destination is a reference to the application's + destination used for comparison + properties: + name: + description: Name is an alternate way of specifying the + target cluster by its symbolic name. This must be set + if Server is not set. + type: string + namespace: + description: Namespace specifies the target namespace + for the application's resources. The namespace will + only be set for namespace-scoped resources that have + not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name + is not set. + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a reference to the application's + ignored differences used for comparison + items: + description: ResourceIgnoreDifferences contains resource + filter and list of json paths which should be ignored + during comparison with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted + managers. Fields mutated by those managers will take + precedence over the desired state defined in the SCM + and won't be displayed in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + source: + description: Source is a reference to the application's source + used for comparison + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block. + ValuesObject takes precedence over Values, so use + one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values to + be passed to helm template, defined as a map. This + takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies whether + to apply env variables substitution for annotation + values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block. ValuesObject takes precedence over Values, + so use one or the other. + type: string + valuesObject: + description: ValuesObject specifies Helm values + to be passed to helm template, defined as a map. + This takes precedence over Values. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonAnnotationsEnvsubst: + description: CommonAnnotationsEnvsubst specifies + whether to apply env variables substitution for + annotation values + type: boolean + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + namespace: + description: Namespace sets the namespace that Kustomize + adds to all resources + type: string + patches: + description: Patches is a list of Kustomize patches + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + description: Replicas is a list of Kustomize Replicas + override specifications + items: + properties: + count: + anyOf: + - type: integer + - type: string + description: Number of replicas + x-kubernetes-int-or-string: true + name: + description: Name of Deployment or StatefulSet + type: string + required: + - count + - name + type: object + type: array + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - destination + type: object + revision: + description: Revision contains information about the revision + the comparison has been performed to + type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array + status: + description: Status is the sync state of the comparison + type: string + required: + - status + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applicationsets.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applicationsets.yaml new file mode 100644 index 000000000..1d20af480 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_applicationsets.yaml @@ -0,0 +1,15057 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: applicationsets.argoproj.io + app.kubernetes.io/part-of: argocd + name: applicationsets.argoproj.io +spec: + group: argoproj.io + names: + kind: ApplicationSet + listKind: ApplicationSetList + plural: applicationsets + shortNames: + - appset + - appsets + singular: applicationset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + applyNestedSelectors: + type: boolean + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + elementsYaml: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + plugin: + properties: + configMapRef: + properties: + name: + type: string + required: + - name + type: object + input: + properties: + parameters: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + pullRequest: + properties: + azuredevops: + properties: + api: + type: string + labels: + items: + type: string + type: array + organization: + type: string + project: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + - project + - repo + type: object + bitbucket: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + bearerToken: + properties: + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - tokenRef + type: object + owner: + type: string + repo: + type: string + required: + - owner + - repo + type: object + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + targetBranchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + insecure: + type: boolean + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + awsCodeCommit: + properties: + allBranches: + type: boolean + region: + type: string + role: + type: string + tagFilters: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + type: object + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSharedProjects: + type: boolean + includeSubgroups: + type: boolean + insecure: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + topic: + type: string + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + goTemplate: + type: boolean + goTemplateOptions: + items: + type: string + type: array + ignoreApplicationDifferences: + items: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + name: + type: string + type: object + type: array + preservedFields: + properties: + annotations: + items: + type: string + type: array + labels: + items: + type: string + type: array + type: object + strategy: + properties: + rollingSync: + properties: + steps: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + maxUpdate: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: + type: string + type: object + syncPolicy: + properties: + applicationsSync: + enum: + - create-only + - create-update + - create-delete + - sync + type: string + preserveResourcesOnDeletion: + type: boolean + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + valuesObject: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonAnnotationsEnvsubst: + type: boolean + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + namespace: + type: string + patches: + items: + properties: + options: + additionalProperties: + type: boolean + type: object + patch: + type: string + path: + type: string + target: + properties: + annotationSelector: + type: string + group: + type: string + kind: + type: string + labelSelector: + type: string + name: + type: string + namespace: + type: string + version: + type: string + type: object + type: object + type: array + replicas: + items: + properties: + count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + name: + type: string + required: + - count + - name + type: object + type: array + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - template + type: object + status: + properties: + applicationStatus: + items: + properties: + application: + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + step: + type: string + required: + - application + - message + - status + - step + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_appprojects.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_appprojects.yaml new file mode 100644 index 000000000..7dd864ed1 --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_appprojects.yaml @@ -0,0 +1,331 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: appprojects.argoproj.io + app.kubernetes.io/part-of: argocd + name: appprojects.argoproj.io +spec: + group: argoproj.io + names: + kind: AppProject + listKind: AppProjectList + plural: appprojects + shortNames: + - appproj + - appprojs + singular: appproject + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'AppProject provides a logical grouping of applications, providing + controls for: * where the apps may deploy to (cluster whitelist) * what + may be deployed (repository whitelist, resource whitelist/blacklist) * who + can access these applications (roles, OIDC group claims bindings) * and + what they can do (RBAC policies) * automation access to these roles (JWT + tokens)' + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AppProjectSpec is the specification of an AppProject + properties: + clusterResourceBlacklist: + description: ClusterResourceBlacklist contains list of blacklisted + cluster level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + clusterResourceWhitelist: + description: ClusterResourceWhitelist contains list of whitelisted + cluster level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + description: + description: Description contains optional project description + type: string + destinations: + description: Destinations contains list of destinations available + for deployment + items: + description: ApplicationDestination holds information about the + application's destination + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name. This must be set if Server is + not set. + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster's + Kubernetes control plane API. This must be set if Name is + not set. + type: string + type: object + type: array + namespaceResourceBlacklist: + description: NamespaceResourceBlacklist contains list of blacklisted + namespace level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + namespaceResourceWhitelist: + description: NamespaceResourceWhitelist contains list of whitelisted + namespace level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + orphanedResources: + description: OrphanedResources specifies if controller should monitor + orphaned resources of apps in this project + properties: + ignore: + description: Ignore contains a list of resources that are to be + excluded from orphaned resources monitoring + items: + description: OrphanedResourceKey is a reference to a resource + to be ignored from + properties: + group: + type: string + kind: + type: string + name: + type: string + type: object + type: array + warn: + description: Warn indicates if warning condition should be created + for apps which have orphaned resources + type: boolean + type: object + permitOnlyProjectScopedClusters: + description: PermitOnlyProjectScopedClusters determines whether destinations + can only reference clusters which are project-scoped + type: boolean + roles: + description: Roles are user defined RBAC roles associated with this + project + items: + description: ProjectRole represents a role that has access to a + project + properties: + description: + description: Description is a description of the role + type: string + groups: + description: Groups are a list of OIDC group claims bound to + this role + items: + type: string + type: array + jwtTokens: + description: JWTTokens are a list of generated JWT tokens bound + to this role + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + name: + description: Name is a name for this role + type: string + policies: + description: Policies Stores a list of casbin formatted strings + that define access policies for the role in the project + items: + type: string + type: array + required: + - name + type: object + type: array + signatureKeys: + description: SignatureKeys contains a list of PGP key IDs that commits + in Git must be signed with in order to be allowed for sync + items: + description: SignatureKey is the specification of a key required + to verify commit signatures with + properties: + keyID: + description: The ID of the key in hexadecimal notation + type: string + required: + - keyID + type: object + type: array + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sourceRepos: + description: SourceRepos contains list of repository URLs which can + be used for deployment + items: + type: string + type: array + syncWindows: + description: SyncWindows controls when syncs can be run for apps in + this project + items: + description: SyncWindow contains the kind, time, duration and attributes + that are used to assign the syncWindows to apps + properties: + applications: + description: Applications contains a list of applications that + the window will apply to + items: + type: string + type: array + clusters: + description: Clusters contains a list of clusters that the window + will apply to + items: + type: string + type: array + duration: + description: Duration is the amount of time the sync window + will be open + type: string + kind: + description: Kind defines if the window allows or blocks syncs + type: string + manualSync: + description: ManualSync enables manual syncs when they would + otherwise be blocked + type: boolean + namespaces: + description: Namespaces contains a list of namespaces that the + window will apply to + items: + type: string + type: array + schedule: + description: Schedule is the time the window will begin, specified + in cron format + type: string + timeZone: + description: TimeZone of the sync that will be applied to the + schedule + type: string + type: object + type: array + type: object + status: + description: AppProjectStatus contains status information for AppProject + CRs + properties: + jwtTokensByRole: + additionalProperties: + description: JWTTokens represents a list of JWT tokens + properties: + items: + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + type: object + description: JWTTokensByRole contains a list of JWT tokens issued + for a given role + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocdexports.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocdexports.yaml new file mode 100644 index 000000000..33c64ec9f --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocdexports.yaml @@ -0,0 +1,300 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + name: argocdexports.argoproj.io +spec: + group: argoproj.io + names: + kind: ArgoCDExport + listKind: ArgoCDExportList + plural: argocdexports + singular: argocdexport + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCDExport is the Schema for the argocdexports API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDExportSpec defines the desired state of ArgoCDExport + properties: + argocd: + description: Argocd is the name of the ArgoCD instance to export. + type: string + image: + description: Image is the container image to use for the export Job. + type: string + schedule: + description: Schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + type: string + storage: + description: Storage defines the storage configuration options. + properties: + backend: + description: Backend defines the storage backend to use, must + be "local" (the default), "aws", "azure" or "gcp". + type: string + pvc: + description: PVC is the desired characteristics for a PersistentVolumeClaim. + properties: + accessModes: + description: 'accessModes contains the desired access modes + the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified data + source, it will create a new volume based on the contents + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will be copied + to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not + be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from which + to populate the volume with data, if a non-empty volume + is desired. This may be any object from a non-empty API + group (non core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed + if the type of the specified object matches some installed + volume populator or dynamic provisioner. This field will + replace the functionality of the dataSource field and as + such if both fields are non-empty, they must have the same + value. For backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource and + dataSourceRef) will be set to the same value automatically + if one of them is empty and the other is non-empty. When + namespace is specified in dataSourceRef, dataSource isn''t + set to the same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, + dataSourceRef allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and generates + an error if a disallowed value is specified. * While dataSource + only allows local objects, dataSourceRef allows objects in + any namespaces. (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource being + referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object is + required in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource feature gate to be + enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources the + volume should have. If RecoverVolumeExpansionFailure feature + is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher + than capacity recorded in the status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required + by the claim. Value of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume + backing this claim. + type: string + type: object + secretName: + description: SecretName is the name of a Secret with encryption + key, credentials, etc. + type: string + type: object + version: + description: Version is the tag/digest to use for the export Job container + image. + type: string + required: + - argocd + type: object + status: + description: ArgoCDExportStatus defines the observed state of ArgoCDExport + properties: + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCDExport + is in its lifecycle. There are five possible phase values: Pending: + The ArgoCDExport has been accepted by the Kubernetes system, but + one or more of the required resources have not been created. Running: + All of the containers for the ArgoCDExport are still running, or + in the process of starting or restarting. Succeeded: All containers + for the ArgoCDExport have terminated in success, and will not be + restarted. Failed: At least one container has terminated in failure, + either exited with non-zero status or was terminated by the system. + Unknown: For some reason the state of the ArgoCDExport could not + be obtained.' + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocds.yaml b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocds.yaml new file mode 100644 index 000000000..242e229ee --- /dev/null +++ b/deploy/olm-catalog/argocd-operator/0.9.0/argoproj.io_argocds.yaml @@ -0,0 +1,13909 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + name: argocds.argoproj.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: argocd-operator-webhook-service + namespace: argocd-operator-system + path: /convert + conversionReviewVersions: + - v1alpha1 + - v1beta1 + group: argoproj.io + names: + kind: ArgoCD + listKind: ArgoCDList + plural: argocds + singular: argocd + scope: Namespaced + versions: + - deprecated: true + deprecationWarning: ArgoCD v1alpha1 version is deprecated and will be converted + to v1beta1 automatically. Moving forward, please use v1beta1 as the ArgoCD API + version. + name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCD is the Schema for the argocds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDSpec defines the desired state of ArgoCD + properties: + applicationInstanceLabelKey: + description: ApplicationInstanceLabelKey is the key name where Argo + CD injects the app name as a tracking label. + type: string + applicationSet: + description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet + controller should be installed. + properties: + env: + description: Env lets you specify environment for applicationSet + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: ExtraCommandArgs allows users to pass command line + arguments to ApplicationSet controller. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the Argo CD ApplicationSet image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for ApplicationSet. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD ApplicationSet image tag. + (optional) + type: string + webhookServer: + description: WebhookServerSpec defines the options for the ApplicationSet + Webhook Server component. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + use for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the + Route resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the + contents of the ca certificate of the final destination. When + using reencrypt termination this file should be + provided in order to have routers use it for health + checks on the secure connection. If this field is + not specified, the router may provide its own destination + CA and perform hostname validation using the short + service name (service.namespace.svc), which allows + infrastructure generated certificates to automatically + verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to + a route. While each router may make its own decisions + on which ports to expose, this is normally port + 80. \n * Allow - traffic is sent to the server on + the insecure port (default) * Disable - no traffic + is allowed on the insecure port. * Redirect - clients + are redirected to the secure port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + type: object + type: object + banner: + description: Banner defines an additional banner to be displayed in + Argo CD UI + properties: + content: + description: Content defines the banner message content to display + type: string + url: + description: URL defines an optional URL to be used as banner + message link + type: string + required: + - content + type: object + configManagementPlugins: + description: ConfigManagementPlugins is used to specify additional + config management plugins. + type: string + controller: + description: Controller defines the Application Controller options + for ArgoCD. + properties: + appSync: + description: "AppSync is used to control the sync frequency, by + default the ArgoCD controller polls Git every 3m. \n Set this + to a duration, e.g. 10m or 600s to control the synchronisation + frequency." + type: string + env: + description: Env lets you specify environment for application + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + logFormat: + description: LogFormat refers to the log format used by the Application + Controller component. Defaults to ArgoCDDefaultLogFormat if + not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level used by the Application + Controller component. Defaults to ArgoCDDefaultLogLevel if not + configured. Valid options are debug, info, error, and warn. + type: string + parallelismLimit: + description: ParallelismLimit defines the limit for parallel kubectl + operations + format: int32 + type: integer + processors: + description: Processors contains the options for the Application + Controller processors. + properties: + operation: + description: Operation is the number of application operation + processors. + format: int32 + type: integer + status: + description: Status is the number of application status processors. + format: int32 + type: integer + type: object + resources: + description: Resources defines the Compute Resources required + by the container for the Application Controller. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + sharding: + description: Sharding contains the options for the Application + Controller sharding configuration. + properties: + clustersPerShard: + description: ClustersPerShard defines the maximum number of + clusters managed by each argocd shard + format: int32 + minimum: 1 + type: integer + dynamicScalingEnabled: + description: DynamicScalingEnabled defines whether dynamic + scaling should be enabled for Application Controller component + type: boolean + enabled: + description: Enabled defines whether sharding should be enabled + on the Application Controller component. + type: boolean + maxShards: + description: MaxShards defines the maximum number of shards + at any given point + format: int32 + type: integer + minShards: + description: MinShards defines the minimum number of shards + at any given point + format: int32 + minimum: 1 + type: integer + replicas: + description: Replicas defines the number of replicas to run + in the Application controller shard. + format: int32 + type: integer + type: object + type: object + dex: + description: Deprecated field. Support dropped in v1beta1 version. + Dex defines the Dex server options for ArgoCD. + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must be a + member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + disableAdmin: + description: DisableAdmin will disable the admin user. + type: boolean + extraConfig: + additionalProperties: + type: string + description: "ExtraConfig can be used to add fields to Argo CD configmap + that are not supported by Argo CD CRD. \n Note: ExtraConfig takes + precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` + = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. + In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] + = true." + type: object + gaAnonymizeUsers: + description: GAAnonymizeUsers toggles user IDs being hashed before + sending to google analytics. + type: boolean + gaTrackingID: + description: GATrackingID is the google analytics tracking ID to use. + type: string + grafana: + description: Grafana defines the Grafana server options for ArgoCD. + properties: + enabled: + description: Enabled will toggle Grafana support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + image: + description: Image is the Grafana container image. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + resources: + description: Resources defines the Compute Resources required + by the container for Grafana. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Grafana Deployment. + format: int32 + type: integer + version: + description: Version is the Grafana container image tag. + type: string + required: + - enabled + type: object + ha: + description: HA options for High Availability support for the Redis + component. + properties: + enabled: + description: Enabled will toggle HA support globally for Argo + CD. + type: boolean + redisProxyImage: + description: RedisProxyImage is the Redis HAProxy container image. + type: string + redisProxyVersion: + description: RedisProxyVersion is the Redis HAProxy container + image tag. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for HA. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - enabled + type: object + helpChatText: + description: HelpChatText is the text for getting chat help, defaults + to "Chat now!" + type: string + helpChatURL: + description: HelpChatURL is the URL for getting chat help, this will + typically be your Slack channel for support. + type: string + image: + description: Image is the ArgoCD container image for all ArgoCD components. + type: string + import: + description: Import is the import/restore options for ArgoCD. + properties: + name: + description: Name of an ArgoCDExport from which to import data. + type: string + namespace: + description: Namespace for the ArgoCDExport, defaults to the same + namespace as the ArgoCD. + type: string + required: + - name + type: object + initialRepositories: + description: InitialRepositories to configure Argo CD with upon creation + of the cluster. + type: string + initialSSHKnownHosts: + description: InitialSSHKnownHosts defines the SSH known hosts data + upon creation of the cluster for connecting Git repositories via + SSH. + properties: + excludedefaulthosts: + description: ExcludeDefaultHosts describes whether you would like + to include the default list of SSH Known Hosts provided by ArgoCD. + type: boolean + keys: + description: Keys describes a custom set of SSH Known Hosts that + you would like to have included in your ArgoCD server. + type: string + type: object + kustomizeBuildOptions: + description: KustomizeBuildOptions is used to specify build options/parameters + to use with `kustomize build`. + type: string + kustomizeVersions: + description: KustomizeVersions is a listing of configured versions + of Kustomize to be made available within ArgoCD. + items: + description: KustomizeVersionSpec is used to specify information + about a kustomize version to be used within ArgoCD. + properties: + path: + description: Path is the path to a configured kustomize version + on the filesystem of your repo server. + type: string + version: + description: Version is a configured kustomize version in the + format of vX.Y.Z + type: string + type: object + type: array + monitoring: + description: Monitoring defines whether workload status monitoring + configuration for this instance. + properties: + enabled: + description: Enabled defines whether workload status monitoring + is enabled for this instance or not + type: boolean + required: + - enabled + type: object + nodePlacement: + description: NodePlacement defines NodeSelectors and Taints for Argo + CD workloads + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a field of PodSpec, it is a map of + key value pairs used for node selection + type: object + tolerations: + description: Tolerations allow the pods to schedule onto nodes + with matching taints + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + notifications: + description: Notifications defines whether the Argo CD Notifications + controller should be installed. + properties: + enabled: + description: Enabled defines whether argocd-notifications controller + should be deployed or not + type: boolean + env: + description: Env let you specify environment variables for Notifications + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Image is the Argo CD Notifications image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas to run for + notifications-controller + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Argo CD Notifications. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD Notifications image tag. (optional) + type: string + required: + - enabled + type: object + oidcConfig: + description: OIDCConfig is the OIDC configuration as an alternative + to dex. + type: string + prometheus: + description: Prometheus defines the Prometheus server options for + ArgoCD. + properties: + enabled: + description: Enabled will toggle Prometheus support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Prometheus StatefulSet. + format: int32 + type: integer + required: + - enabled + type: object + rbac: + description: RBAC defines the RBAC configuration for Argo CD. + properties: + defaultPolicy: + description: DefaultPolicy is the name of the default role which + Argo CD will falls back to, when authorizing API requests (optional). + If omitted or empty, users may be still be able to login, but + will see no apps, projects, etc... + type: string + policy: + description: 'Policy is CSV containing user-defined RBAC policies + and role definitions. Policy rules are in the form: p, subject, + resource, action, object, effect Role definitions and bindings + are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + type: string + policyMatcherMode: + description: PolicyMatcherMode configures the matchers function + mode for casbin. There are two options for this, 'glob' for + glob matcher or 'regex' for regex matcher. + type: string + scopes: + description: 'Scopes controls which OIDC scopes to examine during + rbac enforcement (in addition to `sub` scope). If omitted, defaults + to: ''[groups]''.' + type: string + type: object + redis: + description: Redis defines the Redis server options for ArgoCD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the redis server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + disableTLSVerification: + description: DisableTLSVerification defines whether redis server + API should be accessed using strict TLS validation + type: boolean + image: + description: Image is the Redis container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Redis container image tag. + type: string + type: object + repo: + description: Repo defines the repo server options for Argo CD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the repo server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + env: + description: Env lets you specify environment for repo server + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + execTimeout: + description: ExecTimeout specifies the timeout in seconds for + tool execution + type: integer + extraRepoCommandArgs: + description: Extra Command arguments allows users to pass command + line arguments to repo server workload. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraRepoCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the ArgoCD Repo Server container image. + type: string + initContainers: + description: InitContainers defines the list of initialization + containers for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + logFormat: + description: LogFormat describes the log format that should be + used by the Repo Server. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not + set. Valid options are debug, info, error, and warn. + type: string + mountsatoken: + description: MountSAToken describes whether you would like to + have the Repo server mount the service account token + type: boolean + replicas: + description: Replicas defines the number of replicas for argocd-repo-server. + Value should be greater than or equal to 0. Default is nil. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceaccount: + description: ServiceAccount defines the ServiceAccount user that + you would like the Repo server to use + type: string + sidecarContainers: + description: SidecarContainers defines the list of sidecar containers + for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + verifytls: + description: VerifyTLS defines whether repo server API should + be accessed using strict TLS validation + type: boolean + version: + description: Version is the ArgoCD Repo Server container image + tag. + type: string + volumeMounts: + description: VolumeMounts adds volumeMounts to the repo server + container + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes adds volumes to the repo server deployment + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in + the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is + no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + repositoryCredentials: + description: RepositoryCredentials are the Git pull credentials to + configure Argo CD with upon creation of the cluster. + type: string + resourceActions: + description: ResourceActions customizes resource action behavior. + items: + description: Resource Customization for custom action + properties: + action: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceCustomizations: + description: 'Deprecated field. Support dropped in v1beta1 version. + ResourceCustomizations customizes resource behavior. Keys are in + the form: group/Kind. Please note that this is being deprecated + in favor of ResourceHealthChecks, ResourceIgnoreDifferences, and + ResourceActions.' + type: string + resourceExclusions: + description: ResourceExclusions is used to completely ignore entire + classes of resource group/kinds. + type: string + resourceHealthChecks: + description: ResourceHealthChecks customizes resource health check + behavior. + items: + description: Resource Customization for custom health check + properties: + check: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceIgnoreDifferences: + description: ResourceIgnoreDifferences customizes resource ignore + difference behavior. + properties: + all: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + resourceIdentifiers: + items: + description: Resource Customization fields for ignore difference + properties: + customization: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + group: + type: string + kind: + type: string + type: object + type: array + type: object + resourceInclusions: + description: ResourceInclusions is used to only include specific group/kinds + in the reconciliation process. + type: string + resourceTrackingMethod: + description: ResourceTrackingMethod defines how Argo CD should track + resources that it manages + type: string + server: + description: Server defines the options for the ArgoCD Server component. + properties: + autoscale: + description: Autoscale defines the autoscale options for the Argo + CD Server component. + properties: + enabled: + description: Enabled will toggle autoscaling support for the + Argo CD Server component. + type: boolean + hpa: + description: HPA defines the HorizontalPodAutoscaler options + for the Argo CD Server component. + properties: + maxReplicas: + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. + format: int32 + type: integer + minReplicas: + description: minReplicas is the lower limit for the number + of replicas to which the autoscaler can scale down. It + defaults to 1 pod. minReplicas is allowed to be 0 if + the alpha feature gate HPAScaleToZero is enabled and + at least one Object or External metric is configured. Scaling + is active as long as at least one metric value is available. + format: int32 + type: integer + scaleTargetRef: + description: reference to scaled resource; horizontal + pod autoscaler will learn the current resource consumption + and will set the desired number of pods by using its + Scale subresource. + properties: + apiVersion: + description: apiVersion is the API version of the + referent + type: string + kind: + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + required: + - kind + - name + type: object + targetCPUUtilizationPercentage: + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. + format: int32 + type: integer + required: + - maxReplicas + - scaleTargetRef + type: object + required: + - enabled + type: object + env: + description: Env lets you specify environment for API server pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: Extra Command arguments that would append to the + Argo CD server command. ExtraCommandArgs will not be added, + if one of these commands is already part of the server command + with same or different value. + items: + type: string + type: array + grpc: + description: GRPC defines the state for the Argo CD Server GRPC + options. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for the Argo + CD Server GRPC Ingress. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + type: object + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + insecure: + description: Insecure toggles the insecure flag. + type: boolean + logFormat: + description: LogFormat refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if + not set. Valid options are debug, info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas for argocd-server. + Default is nil. Value should be greater than or equal to 0. + Value will be ignored if Autoscaler is enabled. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for the Argo CD server component. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + service: + description: Service defines the options for the Service backing + the ArgoCD Server component. + properties: + type: + description: Type is the ServiceType to use for the Service + resource. + type: string + required: + - type + type: object + type: object + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sso: + description: SSO defines the Single Sign-on configuration for Argo + CD + properties: + dex: + description: Dex contains the configuration for Argo CD dex authentication + properties: + config: + description: Config is the dex connector configuration. + type: string + groups: + description: Optional list of required groups a user must + be a member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + image: + description: Deprecated field. Support dropped in v1beta1 version. + Image is the SSO container image. + type: string + keycloak: + description: Keycloak contains the configuration for Argo CD keycloak + authentication + properties: + image: + description: Image is the Keycloak container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Keycloak. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + rootCA: + description: Custom root CA certificate for communicating + with the Keycloak OIDC provider + type: string + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the Keycloak container image tag. + type: string + type: object + provider: + description: Provider installs and configures the given SSO Provider + with Argo CD. + type: string + resources: + description: Deprecated field. Support dropped in v1beta1 version. + Resources defines the Compute Resources required by the container + for SSO. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + verifyTLS: + description: Deprecated field. Support dropped in v1beta1 version. + VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Deprecated field. Support dropped in v1beta1 version. + Version is the SSO container image tag. + type: string + type: object + statusBadgeEnabled: + description: StatusBadgeEnabled toggles application status badge feature. + type: boolean + tls: + description: TLS defines the TLS options for ArgoCD. + properties: + ca: + description: CA defines the CA options. + properties: + configMapName: + description: ConfigMapName is the name of the ConfigMap containing + the CA Certificate. + type: string + secretName: + description: SecretName is the name of the Secret containing + the CA Certificate and Key. + type: string + type: object + initialCerts: + additionalProperties: + type: string + description: InitialCerts defines custom TLS certificates upon + creation of the cluster for connecting Git repositories via + HTTPS. + type: object + type: object + usersAnonymousEnabled: + description: UsersAnonymousEnabled toggles anonymous user access. + The anonymous users get default role permissions specified argocd-rbac-cm. + type: boolean + version: + description: Version is the tag to use with the ArgoCD container image + for all ArgoCD components. + type: string + type: object + status: + description: ArgoCDStatus defines the observed state of ArgoCD + properties: + applicationController: + description: 'ApplicationController is a simple, high-level summary + of where the Argo CD application controller component is in its + lifecycle. There are four possible ApplicationController values: + Pending: The Argo CD application controller component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD application controller component are in a Ready state. Failed: + At least one of the Argo CD application controller component Pods + had a failure. Unknown: The state of the Argo CD application controller + component could not be obtained.' + type: string + applicationSetController: + description: 'ApplicationSetController is a simple, high-level summary + of where the Argo CD applicationSet controller component is in its + lifecycle. There are four possible ApplicationSetController values: + Pending: The Argo CD applicationSet controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD applicationSet controller component are in a Ready + state. Failed: At least one of the Argo CD applicationSet controller + component Pods had a failure. Unknown: The state of the Argo CD + applicationSet controller component could not be obtained.' + type: string + host: + description: Host is the hostname of the Ingress. + type: string + notificationsController: + description: 'NotificationsController is a simple, high-level summary + of where the Argo CD notifications controller component is in its + lifecycle. There are four possible NotificationsController values: + Pending: The Argo CD notifications controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD notifications controller component are in a Ready + state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD + notifications controller component could not be obtained.' + type: string + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCD + is in its lifecycle. There are four possible phase values: Pending: + The ArgoCD has been accepted by the Kubernetes system, but one or + more of the required resources have not been created. Available: + All of the resources for the ArgoCD are ready. Failed: At least + one resource has experienced a failure. Unknown: The state of the + ArgoCD phase could not be obtained.' + type: string + redis: + description: 'Redis is a simple, high-level summary of where the Argo + CD Redis component is in its lifecycle. There are four possible + redis values: Pending: The Argo CD Redis component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Redis component are in a Ready state. Failed: At least one + of the Argo CD Redis component Pods had a failure. Unknown: The + state of the Argo CD Redis component could not be obtained.' + type: string + redisTLSChecksum: + description: RedisTLSChecksum contains the SHA256 checksum of the + latest known state of tls.crt and tls.key in the argocd-operator-redis-tls + secret. + type: string + repo: + description: 'Repo is a simple, high-level summary of where the Argo + CD Repo component is in its lifecycle. There are four possible repo + values: Pending: The Argo CD Repo component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Repo component are in a Ready state. Failed: At least one + of the Argo CD Repo component Pods had a failure. Unknown: The + state of the Argo CD Repo component could not be obtained.' + type: string + repoTLSChecksum: + description: RepoTLSChecksum contains the SHA256 checksum of the latest + known state of tls.crt and tls.key in the argocd-repo-server-tls + secret. + type: string + server: + description: 'Server is a simple, high-level summary of where the + Argo CD server component is in its lifecycle. There are four possible + server values: Pending: The Argo CD server component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD server component are in a Ready state. Failed: At least + one of the Argo CD server component Pods had a failure. Unknown: + The state of the Argo CD server component could not be obtained.' + type: string + sso: + description: 'SSO is a simple, high-level summary of where the Argo + CD SSO(Dex/Keycloak) component is in its lifecycle. There are four + possible sso values: Pending: The Argo CD SSO component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD SSO component are in a Ready state. Failed: At least + one of the Argo CD SSO component Pods had a failure. Unknown: The + state of the Argo CD SSO component could not be obtained.' + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ArgoCD is the Schema for the argocds API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ArgoCDSpec defines the desired state of ArgoCD + properties: + applicationInstanceLabelKey: + description: ApplicationInstanceLabelKey is the key name where Argo + CD injects the app name as a tracking label. + type: string + applicationSet: + description: ArgoCDApplicationSet defines whether the Argo CD ApplicationSet + controller should be installed. + properties: + enabled: + description: Enabled is the flag to enable the Application Set + Controller during ArgoCD installation. (optional, default `true`) + type: boolean + env: + description: Env lets you specify environment for applicationSet + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: ExtraCommandArgs allows users to pass command line + arguments to ApplicationSet controller. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the Argo CD ApplicationSet image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the ApplicationSet controller. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for ApplicationSet. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + scmRootCAConfigMap: + description: SCMRootCAConfigMap is the name of the config map + that stores the Gitlab SCM Provider's TLS certificate which + will be mounted on the ApplicationSet Controller (optional). + type: string + version: + description: Version is the Argo CD ApplicationSet image tag. + (optional) + type: string + webhookServer: + description: WebhookServerSpec defines the options for the ApplicationSet + Webhook Server component. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Application set webhook component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + use for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the + Route resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the + contents of the ca certificate of the final destination. When + using reencrypt termination this file should be + provided in order to have routers use it for health + checks on the secure connection. If this field is + not specified, the router may provide its own destination + CA and perform hostname validation using the short + service name (service.namespace.svc), which allows + infrastructure generated certificates to automatically + verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to + a route. While each router may make its own decisions + on which ports to expose, this is normally port + 80. \n * Allow - traffic is sent to the server on + the insecure port (default) * Disable - no traffic + is allowed on the insecure port. * Redirect - clients + are redirected to the secure port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + type: object + type: object + banner: + description: Banner defines an additional banner to be displayed in + Argo CD UI + properties: + content: + description: Content defines the banner message content to display + type: string + url: + description: URL defines an optional URL to be used as banner + message link + type: string + required: + - content + type: object + configManagementPlugins: + description: ConfigManagementPlugins is used to specify additional + config management plugins. + type: string + controller: + description: Controller defines the Application Controller options + for ArgoCD. + properties: + appSync: + description: "AppSync is used to control the sync frequency, by + default the ArgoCD controller polls Git every 3m. \n Set this + to a duration, e.g. 10m or 600s to control the synchronisation + frequency." + type: string + enabled: + description: Enabled is the flag to enable the Application Controller + during ArgoCD installation. (optional, default `true`) + type: boolean + env: + description: Env lets you specify environment for application + controller pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + logFormat: + description: LogFormat refers to the log format used by the Application + Controller component. Defaults to ArgoCDDefaultLogFormat if + not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level used by the Application + Controller component. Defaults to ArgoCDDefaultLogLevel if not + configured. Valid options are debug, info, error, and warn. + type: string + parallelismLimit: + description: ParallelismLimit defines the limit for parallel kubectl + operations + format: int32 + type: integer + processors: + description: Processors contains the options for the Application + Controller processors. + properties: + operation: + description: Operation is the number of application operation + processors. + format: int32 + type: integer + status: + description: Status is the number of application status processors. + format: int32 + type: integer + type: object + resources: + description: Resources defines the Compute Resources required + by the container for the Application Controller. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + sharding: + description: Sharding contains the options for the Application + Controller sharding configuration. + properties: + clustersPerShard: + description: ClustersPerShard defines the maximum number of + clusters managed by each argocd shard + format: int32 + minimum: 1 + type: integer + dynamicScalingEnabled: + description: DynamicScalingEnabled defines whether dynamic + scaling should be enabled for Application Controller component + type: boolean + enabled: + description: Enabled defines whether sharding should be enabled + on the Application Controller component. + type: boolean + maxShards: + description: MaxShards defines the maximum number of shards + at any given point + format: int32 + type: integer + minShards: + description: MinShards defines the minimum number of shards + at any given point + format: int32 + minimum: 1 + type: integer + replicas: + description: Replicas defines the number of replicas to run + in the Application controller shard. + format: int32 + type: integer + type: object + type: object + disableAdmin: + description: DisableAdmin will disable the admin user. + type: boolean + extraConfig: + additionalProperties: + type: string + description: "ExtraConfig can be used to add fields to Argo CD configmap + that are not supported by Argo CD CRD. \n Note: ExtraConfig takes + precedence over Argo CD CRD. For example, A user sets `argocd.Spec.DisableAdmin` + = true and also `a.Spec.ExtraConfig[\"admin.enabled\"]` = true. + In this case, operator updates Argo CD Configmap as follows -> argocd-cm.Data[\"admin.enabled\"] + = true." + type: object + gaAnonymizeUsers: + description: GAAnonymizeUsers toggles user IDs being hashed before + sending to google analytics. + type: boolean + gaTrackingID: + description: GATrackingID is the google analytics tracking ID to use. + type: string + grafana: + description: Grafana defines the Grafana server options for ArgoCD. + properties: + enabled: + description: Enabled will toggle Grafana support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + image: + description: Image is the Grafana container image. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + resources: + description: Resources defines the Compute Resources required + by the container for Grafana. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Grafana component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Grafana Deployment. + format: int32 + type: integer + version: + description: Version is the Grafana container image tag. + type: string + required: + - enabled + type: object + ha: + description: HA options for High Availability support for the Redis + component. + properties: + enabled: + description: Enabled will toggle HA support globally for Argo + CD. + type: boolean + redisProxyImage: + description: RedisProxyImage is the Redis HAProxy container image. + type: string + redisProxyVersion: + description: RedisProxyVersion is the Redis HAProxy container + image tag. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for HA. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - enabled + type: object + helpChatText: + description: HelpChatText is the text for getting chat help, defaults + to "Chat now!" + type: string + helpChatURL: + description: HelpChatURL is the URL for getting chat help, this will + typically be your Slack channel for support. + type: string + image: + description: Image is the ArgoCD container image for all ArgoCD components. + type: string + import: + description: Import is the import/restore options for ArgoCD. + properties: + name: + description: Name of an ArgoCDExport from which to import data. + type: string + namespace: + description: Namespace for the ArgoCDExport, defaults to the same + namespace as the ArgoCD. + type: string + required: + - name + type: object + initialRepositories: + description: InitialRepositories to configure Argo CD with upon creation + of the cluster. + type: string + initialSSHKnownHosts: + description: InitialSSHKnownHosts defines the SSH known hosts data + upon creation of the cluster for connecting Git repositories via + SSH. + properties: + excludedefaulthosts: + description: ExcludeDefaultHosts describes whether you would like + to include the default list of SSH Known Hosts provided by ArgoCD. + type: boolean + keys: + description: Keys describes a custom set of SSH Known Hosts that + you would like to have included in your ArgoCD server. + type: string + type: object + kustomizeBuildOptions: + description: KustomizeBuildOptions is used to specify build options/parameters + to use with `kustomize build`. + type: string + kustomizeVersions: + description: KustomizeVersions is a listing of configured versions + of Kustomize to be made available within ArgoCD. + items: + description: KustomizeVersionSpec is used to specify information + about a kustomize version to be used within ArgoCD. + properties: + path: + description: Path is the path to a configured kustomize version + on the filesystem of your repo server. + type: string + version: + description: Version is a configured kustomize version in the + format of vX.Y.Z + type: string + type: object + type: array + monitoring: + description: Monitoring defines whether workload status monitoring + configuration for this instance. + properties: + enabled: + description: Enabled defines whether workload status monitoring + is enabled for this instance or not + type: boolean + required: + - enabled + type: object + nodePlacement: + description: NodePlacement defines NodeSelectors and Taints for Argo + CD workloads + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a field of PodSpec, it is a map of + key value pairs used for node selection + type: object + tolerations: + description: Tolerations allow the pods to schedule onto nodes + with matching taints + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + notifications: + description: Notifications defines whether the Argo CD Notifications + controller should be installed. + properties: + enabled: + description: Enabled defines whether argocd-notifications controller + should be deployed or not + type: boolean + env: + description: Env let you specify environment variables for Notifications + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + description: Image is the Argo CD Notifications image (optional) + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the argocd-notifications. Defaults to ArgoCDDefaultLogLevel + if not set. Valid options are debug,info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas to run for + notifications-controller + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Argo CD Notifications. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Argo CD Notifications image tag. (optional) + type: string + required: + - enabled + type: object + oidcConfig: + description: OIDCConfig is the OIDC configuration as an alternative + to dex. + type: string + prometheus: + description: Prometheus defines the Prometheus server options for + ArgoCD. + properties: + enabled: + description: Enabled will toggle Prometheus support globally for + ArgoCD. + type: boolean + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Prometheus component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + size: + description: Size is the replica count for the Prometheus StatefulSet. + format: int32 + type: integer + required: + - enabled + type: object + rbac: + description: RBAC defines the RBAC configuration for Argo CD. + properties: + defaultPolicy: + description: DefaultPolicy is the name of the default role which + Argo CD will falls back to, when authorizing API requests (optional). + If omitted or empty, users may be still be able to login, but + will see no apps, projects, etc... + type: string + policy: + description: 'Policy is CSV containing user-defined RBAC policies + and role definitions. Policy rules are in the form: p, subject, + resource, action, object, effect Role definitions and bindings + are in the form: g, subject, inherited-subject See https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + for additional information.' + type: string + policyMatcherMode: + description: PolicyMatcherMode configures the matchers function + mode for casbin. There are two options for this, 'glob' for + glob matcher or 'regex' for regex matcher. + type: string + scopes: + description: 'Scopes controls which OIDC scopes to examine during + rbac enforcement (in addition to `sub` scope). If omitted, defaults + to: ''[groups]''.' + type: string + type: object + redis: + description: Redis defines the Redis server options for ArgoCD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the redis server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + disableTLSVerification: + description: DisableTLSVerification defines whether redis server + API should be accessed using strict TLS validation + type: boolean + enabled: + description: Enabled is the flag to enable Redis during ArgoCD + installation. (optional, default `true`) + type: boolean + image: + description: Image is the Redis container image. + type: string + remote: + description: Remote specifies the remote URL of the Redis container. + (optional, by default, a local instance managed by the operator + is used.) + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Redis container image tag. + type: string + type: object + repo: + description: Repo defines the repo server options for Argo CD. + properties: + autotls: + description: 'AutoTLS specifies the method to use for automatic + TLS configuration for the repo server The value specified here + can currently be: - openshift - Use the OpenShift service CA + to request TLS config' + type: string + enabled: + description: Enabled is the flag to enable Repo Server during + ArgoCD installation. (optional, default `true`) + type: boolean + env: + description: Env lets you specify environment for repo server + pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + execTimeout: + description: ExecTimeout specifies the timeout in seconds for + tool execution + type: integer + extraRepoCommandArgs: + description: Extra Command arguments allows users to pass command + line arguments to repo server workload. They get added to default + command line arguments provided by the operator. Please note + that the command line arguments provided as part of ExtraRepoCommandArgs + will not overwrite the default command line arguments. + items: + type: string + type: array + image: + description: Image is the ArgoCD Repo Server container image. + type: string + initContainers: + description: InitContainers defines the list of initialization + containers for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + logFormat: + description: LogFormat describes the log format that should be + used by the Repo Server. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel describes the log level that should be used + by the Repo Server. Defaults to ArgoCDDefaultLogLevel if not + set. Valid options are debug, info, error, and warn. + type: string + mountsatoken: + description: MountSAToken describes whether you would like to + have the Repo server mount the service account token + type: boolean + remote: + description: Remote specifies the remote URL of the Repo Server + container. (optional, by default, a local instance managed by + the operator is used.) + type: string + replicas: + description: Replicas defines the number of replicas for argocd-repo-server. + Value should be greater than or equal to 0. Default is nil. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for Redis. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceaccount: + description: ServiceAccount defines the ServiceAccount user that + you would like the Repo server to use + type: string + sidecarContainers: + description: SidecarContainers defines the list of sidecar containers + for the repo server deployment + items: + description: A single application container that you want to + run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never be expanded, + regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not + provided. Variable references $(VAR_NAME) are expanded + using the container''s environment. If a variable cannot + be resolved, the reference in the input string will be + unchanged. Double $$ are reduced to a single $, which + allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the + container. Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are + expanded using the previously defined environment + variables in the container and any service environment + variables. If a variable cannot be resolved, the + reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". Escaped + references will never be expanded, regardless of + whether the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the + pod's namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or + its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must + be a C_IDENTIFIER. All invalid keys will be reported as + an event when the container is starting. When a key exists + in multiple sources, the value associated with the last + source will take precedence. Values defined by an Env + with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a + set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must + be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to + each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be + defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after + a container is created. If the handler fails, the + container is terminated and restarted according to + its restart policy. Other management of the container + blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a + container is terminated due to an API request or management + event such as liveness/startup probe failure, preemption, + resource contention, etc. The handler is not called + if the container crashes or exits. The Pod''s termination + grace period countdown begins before the PreStop hook + is executed. Regardless of the outcome of the handler, + the container will eventually terminate within the + Pod''s termination grace period (unless delayed by + finalizers). Other management of the container blocks + until the hook completes or until the termination + grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to + execute inside the container, the working + directory for the command is root ('/') in + the container's filesystem. The command is + simply exec'd, it is not run inside a shell, + so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is + treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set "Host" + in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name. This + will be canonicalized upon output, so + case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to + the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward + compatibility. There are no validation of this + field and lifecycle hooks will fail in runtime + when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that port + from being exposed. Any port which is listening on the + default "0.0.0.0" address inside a container will be accessible + from the network. Modifying this array with strategic + merge patch may corrupt the data. For more information + See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in + a single container. + properties: + containerPort: + description: Number of port to expose on the pod's + IP address. This must be a valid port number, 0 + < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port + to. + type: string + hostPort: + description: Number of port to expose on the host. + If specified, this must be a valid port number, + 0 < x < 65536. If HostNetwork is specified, this + must match ContainerPort. Most containers do not + need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a + pod must have a unique name. Name for the port that + can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, + or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the + probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified + resource is resized. If not specified, it defaults + to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in + PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where + this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior + of individual containers in a pod. This field may only + be set for init containers, and the only allowed value + is "Always". For non-init containers or when this field + is not specified, the restart behavior is defined by the + Pod''s restart policy and the container type. Setting + the RestartPolicy as "Always" for the init container will + have the following effect: this init container will be + continually restarted on exit until all regular containers + have terminated. Once all regular containers have completed, + all init containers with restartPolicy "Always" will be + shut down. This lifecycle differs from normal init containers + and is often referred to as a "sidecar" container. Although + this init container still starts in the init container + sequence, it does not wait for the container to complete + before proceeding to the next init container. Instead, + the next init container starts immediately after this + init container is started, or after any startupProbe has + successfully completed.' + type: string + securityContext: + description: 'SecurityContext defines the security options + the container should be run with. If set, the fields of + SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent + process. This bool directly controls if the no_new_privs + flag will be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be + set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running + containers. Defaults to the default set of capabilities + granted by the container runtime. Note that this field + cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent + to root on the host. Defaults to false. Note that + this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount + to use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that this + field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as + a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not run + as UID 0 (root) and fail to start the container if + it does. If unset or false, no such validation will + be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the + container. If unspecified, the container runtime will + allocate a random SELinux context for each container. May + also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is + windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & + container level, the container options override the + pod options. Note that this field cannot be set when + spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative to + the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: \n + Localhost - a profile defined in a file on the + node should be used. RuntimeDefault - the container + runtime default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to + all containers. If unspecified, the options from the + PodSecurityContext will be used. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set + when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec + named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a + mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true + then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed + until this completes successfully. If this probe fails, + the Pod will be restarted, just as if the livenessProbe + failed. This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it might + take a long time to load data or warm a cache, than during + steady-state operation. This cannot be updated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC + port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service + to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum + value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, + the pod's terminationGracePeriodSeconds will be used. + Otherwise, this value overrides the value provided + by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the + kill signal (no opportunity to shut down). This is + a beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe + times out. Defaults to 1 second. Minimum value is + 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, + reads from stdin in the container will always result in + EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close + the stdin channel after it has been opened by a single + attach. When stdin is true the stdin stream will remain + open across multiple attach sessions. If stdinOnce is + set to true, stdin is opened on container start, is empty + until the first client attaches to stdin, and then remains + open and accepts data until the client disconnects, at + which time stdin is closed and remains closed until the + container is restarted. If this flag is false, a container + processes that reads from stdin will never receive an + EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which + the container''s termination message will be written is + mounted into the container''s filesystem. Message written + is intended to be brief final status, such as an assertion + failure message. Will be truncated by the node if greater + than 4096 bytes. The total message length across all containers + will be limited to 12kb. Defaults to /dev/termination-log. + Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should + be populated. File will use the contents of terminationMessagePath + to populate the container status message on both success + and failure. FallbackToLogsOnError will use the last chunk + of container log output if the termination message file + is empty and the container exited with an error. The log + output is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY + for itself, also requires 'stdin' to be true. Default + is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a raw + block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the + container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the + container's volume should be mounted. Defaults to + "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from + which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable + references $(VAR_NAME) are expanded using the container's + environment. Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + verifytls: + description: VerifyTLS defines whether repo server API should + be accessed using strict TLS validation + type: boolean + version: + description: Version is the ArgoCD Repo Server container image + tag. + type: string + volumeMounts: + description: VolumeMounts adds volumeMounts to the repo server + container + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes adds volumes to the repo server deployment + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in + the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of + resources, defined in spec.resourceClaims, + that are used by this container. \n This + is an alpha field and requires enabling + the DynamicResourceAllocation feature + gate. \n This field is immutable. It can + only be set for containers." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is + no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + repositoryCredentials: + description: RepositoryCredentials are the Git pull credentials to + configure Argo CD with upon creation of the cluster. + type: string + resourceActions: + description: ResourceActions customizes resource action behavior. + items: + description: Resource Customization for custom action + properties: + action: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceExclusions: + description: ResourceExclusions is used to completely ignore entire + classes of resource group/kinds. + type: string + resourceHealthChecks: + description: ResourceHealthChecks customizes resource health check + behavior. + items: + description: Resource Customization for custom health check + properties: + check: + type: string + group: + type: string + kind: + type: string + type: object + type: array + resourceIgnoreDifferences: + description: ResourceIgnoreDifferences customizes resource ignore + difference behavior. + properties: + all: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + resourceIdentifiers: + items: + description: Resource Customization fields for ignore difference + properties: + customization: + properties: + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + managedFieldsManagers: + items: + type: string + type: array + type: object + group: + type: string + kind: + type: string + type: object + type: array + type: object + resourceInclusions: + description: ResourceInclusions is used to only include specific group/kinds + in the reconciliation process. + type: string + resourceTrackingMethod: + description: ResourceTrackingMethod defines how Argo CD should track + resources that it manages + type: string + server: + description: Server defines the options for the ArgoCD Server component. + properties: + autoscale: + description: Autoscale defines the autoscale options for the Argo + CD Server component. + properties: + enabled: + description: Enabled will toggle autoscaling support for the + Argo CD Server component. + type: boolean + hpa: + description: HPA defines the HorizontalPodAutoscaler options + for the Argo CD Server component. + properties: + maxReplicas: + description: maxReplicas is the upper limit for the number + of pods that can be set by the autoscaler; cannot be + smaller than MinReplicas. + format: int32 + type: integer + minReplicas: + description: minReplicas is the lower limit for the number + of replicas to which the autoscaler can scale down. It + defaults to 1 pod. minReplicas is allowed to be 0 if + the alpha feature gate HPAScaleToZero is enabled and + at least one Object or External metric is configured. Scaling + is active as long as at least one metric value is available. + format: int32 + type: integer + scaleTargetRef: + description: reference to scaled resource; horizontal + pod autoscaler will learn the current resource consumption + and will set the desired number of pods by using its + Scale subresource. + properties: + apiVersion: + description: apiVersion is the API version of the + referent + type: string + kind: + description: 'kind is the kind of the referent; More + info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'name is the name of the referent; More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + required: + - kind + - name + type: object + targetCPUUtilizationPercentage: + description: targetCPUUtilizationPercentage is the target + average CPU utilization (represented as a percentage + of requested CPU) over all the pods; if not specified + the default autoscaling policy will be used. + format: int32 + type: integer + required: + - maxReplicas + - scaleTargetRef + type: object + required: + - enabled + type: object + enabled: + description: Enabled is the flag to enable ArgoCD Server during + ArgoCD installation. (optional, default `true`) + type: boolean + env: + description: Env lets you specify environment for API server pods + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + extraCommandArgs: + description: Extra Command arguments that would append to the + Argo CD server command. ExtraCommandArgs will not be added, + if one of these commands is already part of the server command + with same or different value. + items: + type: string + type: array + grpc: + description: GRPC defines the state for the Argo CD Server GRPC + options. + properties: + host: + description: Host is the hostname to use for Ingress/Route + resources. + type: string + ingress: + description: Ingress defines the desired state for the Argo + CD Server GRPC Ingress. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to + apply to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress + only supports a single TLS port, 443. If multiple members + of this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified + through the SNI TLS extension, if the ingress controller + fulfilling the ingress supports SNI. + items: + description: IngressTLS describes the transport layer + security associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in + the TLS certificate. The values in this list must + match the name/s used in the tlsSecret. Defaults + to the wildcard host setting for the loadbalancer + controller fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret + used to terminate TLS traffic on port 443. Field + is left optional to allow TLS routing based on + SNI hostname alone. If the SNI host in a listener + conflicts with the "Host" header field used by + an IngressRule, the SNI host is used for termination + and value of the "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + type: object + host: + description: Host is the hostname to use for Ingress/Route resources. + type: string + ingress: + description: Ingress defines the desired state for an Ingress + for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to apply + to the Ingress. + type: object + enabled: + description: Enabled will toggle the creation of the Ingress. + type: boolean + ingressClassName: + description: IngressClassName for the Ingress resource. + type: string + path: + description: Path used for the Ingress resource. + type: string + tls: + description: TLS configuration. Currently the Ingress only + supports a single TLS port, 443. If multiple members of + this list specify different hosts, they will be multiplexed + on the same port according to the hostname specified through + the SNI TLS extension, if the ingress controller fulfilling + the ingress supports SNI. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: hosts is a list of hosts included in the + TLS certificate. The values in this list must match + the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller + fulfilling this Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: secretName is the name of the secret used + to terminate TLS traffic on port 443. Field is left + optional to allow TLS routing based on SNI hostname + alone. If the SNI host in a listener conflicts with + the "Host" header field used by an IngressRule, the + SNI host is used for termination and value of the + "Host" header is used for routing. + type: string + type: object + type: array + required: + - enabled + type: object + insecure: + description: Insecure toggles the insecure flag. + type: boolean + logFormat: + description: LogFormat refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogFormat + if not configured. Valid options are text or json. + type: string + logLevel: + description: LogLevel refers to the log level to be used by the + ArgoCD Server component. Defaults to ArgoCDDefaultLogLevel if + not set. Valid options are debug, info, error, and warn. + type: string + replicas: + description: Replicas defines the number of replicas for argocd-server. + Default is nil. Value should be greater than or equal to 0. + Value will be ignored if Autoscaler is enabled. + format: int32 + type: integer + resources: + description: Resources defines the Compute Resources required + by the container for the Argo CD server component. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + route: + description: Route defines the desired state for an OpenShift + Route for the Argo CD Server component. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is the map of annotations to use + for the Route resource. + type: object + enabled: + description: Enabled will toggle the creation of the OpenShift + Route. + type: boolean + labels: + additionalProperties: + type: string + description: Labels is the map of labels to use for the Route + resource + type: object + path: + description: Path the router watches for, to route traffic + for to the service. + type: string + tls: + description: TLS provides the ability to configure certificates + and termination for the Route. + properties: + caCertificate: + description: caCertificate provides the cert authority + certificate contents + type: string + certificate: + description: certificate provides certificate contents + type: string + destinationCACertificate: + description: destinationCACertificate provides the contents + of the ca certificate of the final destination. When + using reencrypt termination this file should be provided + in order to have routers use it for health checks on + the secure connection. If this field is not specified, + the router may provide its own destination CA and perform + hostname validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to + automatically verify. + type: string + insecureEdgeTerminationPolicy: + description: "insecureEdgeTerminationPolicy indicates + the desired behavior for insecure connections to a route. + While each router may make its own decisions on which + ports to expose, this is normally port 80. \n * Allow + - traffic is sent to the server on the insecure port + (default) * Disable - no traffic is allowed on the insecure + port. * Redirect - clients are redirected to the secure + port." + type: string + key: + description: key provides key file contents + type: string + termination: + description: termination indicates termination type. + type: string + required: + - termination + type: object + wildcardPolicy: + description: WildcardPolicy if any for the route. Currently + only 'Subdomain' or 'None' is allowed. + type: string + required: + - enabled + type: object + service: + description: Service defines the options for the Service backing + the ArgoCD Server component. + properties: + type: + description: Type is the ServiceType to use for the Service + resource. + type: string + required: + - type + type: object + type: object + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sso: + description: SSO defines the Single Sign-on configuration for Argo + CD + properties: + dex: + description: Dex contains the configuration for Argo CD dex authentication + properties: + config: + description: Config is the dex connector configuration. + type: string + env: + description: Env lets you specify environment variables for + Dex. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must + be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables + in the container and any service environment variables. + If a variable cannot be resolved, the reference in + the input string will be unchanged. Double $$ are + reduced to a single $, which allows for escaping the + $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the + variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + groups: + description: Optional list of required groups a user must + be a member of + items: + type: string + type: array + image: + description: Image is the Dex container image. + type: string + openShiftOAuth: + description: OpenShiftOAuth enables OpenShift OAuth authentication + for the Dex server. + type: boolean + resources: + description: Resources defines the Compute Resources required + by the container for Dex. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Version is the Dex container image tag. + type: string + type: object + keycloak: + description: Keycloak contains the configuration for Argo CD keycloak + authentication + properties: + image: + description: Image is the Keycloak container image. + type: string + resources: + description: Resources defines the Compute Resources required + by the container for Keycloak. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. \n This field + is immutable. It can only be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + rootCA: + description: Custom root CA certificate for communicating + with the Keycloak OIDC provider + type: string + verifyTLS: + description: VerifyTLS set to false disables strict TLS validation. + type: boolean + version: + description: Version is the Keycloak container image tag. + type: string + type: object + provider: + description: Provider installs and configures the given SSO Provider + with Argo CD. + type: string + type: object + statusBadgeEnabled: + description: StatusBadgeEnabled toggles application status badge feature. + type: boolean + tls: + description: TLS defines the TLS options for ArgoCD. + properties: + ca: + description: CA defines the CA options. + properties: + configMapName: + description: ConfigMapName is the name of the ConfigMap containing + the CA Certificate. + type: string + secretName: + description: SecretName is the name of the Secret containing + the CA Certificate and Key. + type: string + type: object + initialCerts: + additionalProperties: + type: string + description: InitialCerts defines custom TLS certificates upon + creation of the cluster for connecting Git repositories via + HTTPS. + type: object + type: object + usersAnonymousEnabled: + description: UsersAnonymousEnabled toggles anonymous user access. + The anonymous users get default role permissions specified argocd-rbac-cm. + type: boolean + version: + description: Version is the tag to use with the ArgoCD container image + for all ArgoCD components. + type: string + type: object + status: + description: ArgoCDStatus defines the observed state of ArgoCD + properties: + applicationController: + description: 'ApplicationController is a simple, high-level summary + of where the Argo CD application controller component is in its + lifecycle. There are four possible ApplicationController values: + Pending: The Argo CD application controller component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD application controller component are in a Ready state. Failed: + At least one of the Argo CD application controller component Pods + had a failure. Unknown: The state of the Argo CD application controller + component could not be obtained.' + type: string + applicationSetController: + description: 'ApplicationSetController is a simple, high-level summary + of where the Argo CD applicationSet controller component is in its + lifecycle. There are four possible ApplicationSetController values: + Pending: The Argo CD applicationSet controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD applicationSet controller component are in a Ready + state. Failed: At least one of the Argo CD applicationSet controller + component Pods had a failure. Unknown: The state of the Argo CD + applicationSet controller component could not be obtained.' + type: string + host: + description: Host is the hostname of the Ingress. + type: string + notificationsController: + description: 'NotificationsController is a simple, high-level summary + of where the Argo CD notifications controller component is in its + lifecycle. There are four possible NotificationsController values: + Pending: The Argo CD notifications controller component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD notifications controller component are in a Ready + state. Failed: At least one of the Argo CD notifications controller + component Pods had a failure. Unknown: The state of the Argo CD + notifications controller component could not be obtained.' + type: string + phase: + description: 'Phase is a simple, high-level summary of where the ArgoCD + is in its lifecycle. There are four possible phase values: Pending: + The ArgoCD has been accepted by the Kubernetes system, but one or + more of the required resources have not been created. Available: + All of the resources for the ArgoCD are ready. Failed: At least + one resource has experienced a failure. Unknown: The state of the + ArgoCD phase could not be obtained.' + type: string + redis: + description: 'Redis is a simple, high-level summary of where the Argo + CD Redis component is in its lifecycle. There are four possible + redis values: Pending: The Argo CD Redis component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Redis component are in a Ready state. Failed: At least one + of the Argo CD Redis component Pods had a failure. Unknown: The + state of the Argo CD Redis component could not be obtained.' + type: string + redisTLSChecksum: + description: RedisTLSChecksum contains the SHA256 checksum of the + latest known state of tls.crt and tls.key in the argocd-operator-redis-tls + secret. + type: string + repo: + description: 'Repo is a simple, high-level summary of where the Argo + CD Repo component is in its lifecycle. There are four possible repo + values: Pending: The Argo CD Repo component has been accepted by + the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD Repo component are in a Ready state. Failed: At least one + of the Argo CD Repo component Pods had a failure. Unknown: The + state of the Argo CD Repo component could not be obtained.' + type: string + repoTLSChecksum: + description: RepoTLSChecksum contains the SHA256 checksum of the latest + known state of tls.crt and tls.key in the argocd-repo-server-tls + secret. + type: string + server: + description: 'Server is a simple, high-level summary of where the + Argo CD server component is in its lifecycle. There are four possible + server values: Pending: The Argo CD server component has been accepted + by the Kubernetes system, but one or more of the required resources + have not been created. Running: All of the required Pods for the + Argo CD server component are in a Ready state. Failed: At least + one of the Argo CD server component Pods had a failure. Unknown: + The state of the Argo CD server component could not be obtained.' + type: string + sso: + description: 'SSO is a simple, high-level summary of where the Argo + CD SSO(Dex/Keycloak) component is in its lifecycle. There are four + possible sso values: Pending: The Argo CD SSO component has been + accepted by the Kubernetes system, but one or more of the required + resources have not been created. Running: All of the required Pods + for the Argo CD SSO component are in a Ready state. Failed: At least + one of the Argo CD SSO component Pods had a failure. Unknown: The + state of the Argo CD SSO component could not be obtained.' + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/tests/k8s/1-027_validate_applicationset_status/03-change-appset-image.yaml b/tests/k8s/1-027_validate_applicationset_status/03-change-appset-image.yaml index a427db2a7..407017280 100644 --- a/tests/k8s/1-027_validate_applicationset_status/03-change-appset-image.yaml +++ b/tests/k8s/1-027_validate_applicationset_status/03-change-appset-image.yaml @@ -4,4 +4,4 @@ metadata: name: example-argocd spec: applicationSet: - image: quay.io/argoproj/argocd@sha256:8283a9f06033c2377dc61b03daf49 \ No newline at end of file + image: quay.io/argoproj/argocd@sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc \ No newline at end of file From c238af601bb59097ae446f9727807e77b259f04b Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:34:31 +0530 Subject: [PATCH 41/94] fix the logic for applicationset resources reconcilation when spec.applicationset.enabled is false (#1089) * fix the logic for applicationset resources reconciliation when spec.applicationset.enabled is false Signed-off-by: ishitasequeira Signed-off-by: Raghavi Shirur Signed-off-by: ishitasequeira * fix tests Signed-off-by: ishitasequeira Signed-off-by: Raghavi Shirur Signed-off-by: ishitasequeira * delete repo server when repo.enabled is set to false Signed-off-by: ishitasequeira Signed-off-by: Raghavi Shirur Signed-off-by: ishitasequeira * Update status.Phase based on component enabled flag Signed-off-by: ishitasequeira Signed-off-by: Raghavi Shirur Signed-off-by: ishitasequeira * Added kuttl tests Signed-off-by: Raghavi Shirur Signed-off-by: ishitasequeira * Added namespace creation step Signed-off-by: Raghavi Shirur Signed-off-by: ishitasequeira * delete services created for resources Signed-off-by: ishitasequeira * delete server deployment when enabled flag set to false Signed-off-by: ishitasequeira * fix e2e test Signed-off-by: ishitasequeira * fix log message Signed-off-by: ishitasequeira * revert kuttl test timeout Signed-off-by: ishitasequeira * Added test for reverse scenario Signed-off-by: Raghavi Shirur * Dir rename Signed-off-by: Raghavi Shirur * Added e2e test for ha mode Signed-off-by: Raghavi Shirur --------- Signed-off-by: ishitasequeira Signed-off-by: Raghavi Shirur Co-authored-by: Raghavi Shirur --- controllers/argocd/applicationset.go | 29 +++++---- controllers/argocd/applicationset_test.go | 1 + controllers/argocd/deployment.go | 8 +-- controllers/argocd/service.go | 31 ++++++--- controllers/argocd/status.go | 5 +- .../01-errors.yaml | 63 +++++++++++++++++++ .../01-install.yaml | 22 +++++++ .../02-assert.yaml | 25 ++++++++ .../02-errors.yaml | 34 ++++++++++ .../02-install.yaml | 16 +++++ .../03-assert.yaml | 35 +++++++++++ .../03-errors.yaml | 26 ++++++++ .../03-install.yaml | 16 +++++ .../04-assert.yaml | 42 +++++++++++++ .../04-errors.yaml | 20 ++++++ .../04-install.yaml | 16 +++++ .../05-assert.yaml | 49 +++++++++++++++ .../05-errors.yaml | 13 ++++ .../05-install.yaml | 16 +++++ .../06-assert.yaml | 50 +++++++++++++++ .../06-install.yaml | 16 +++++ .../01-assert.yaml | 50 +++++++++++++++ .../01-install.yaml | 22 +++++++ .../02-assert.yaml | 41 ++++++++++++ .../02-errors.yaml | 20 ++++++ .../02-install.yaml | 16 +++++ .../03-assert.yaml | 41 ++++++++++++ .../03-errors.yaml | 18 ++++++ .../03-install.yaml | 16 +++++ .../04-assert.yaml | 34 ++++++++++ .../04-errors.yaml | 29 +++++++++ .../04-install.yaml | 16 +++++ .../05-assert.yaml | 27 ++++++++ .../05-errors.yaml | 40 ++++++++++++ .../05-install.yaml | 16 +++++ .../06-errors.yaml | 37 +++++++++++ .../06-install.yaml | 16 +++++ .../07-errors.yaml | 37 +++++++++++ .../07-install.yaml | 18 ++++++ 39 files changed, 1000 insertions(+), 27 deletions(-) create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-errors.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-install.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-assert.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-errors.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-install.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-assert.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-errors.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-install.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-assert.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-errors.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-install.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-assert.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-errors.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-install.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-assert.yaml create mode 100644 tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-assert.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-assert.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-errors.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-assert.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-errors.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-assert.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-errors.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-assert.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-errors.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-errors.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-install.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-errors.yaml create mode 100644 tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-install.yaml diff --git a/controllers/argocd/applicationset.go b/controllers/argocd/applicationset.go index dded2ebcd..3eb850ea7 100644 --- a/controllers/argocd/applicationset.go +++ b/controllers/argocd/applicationset.go @@ -110,8 +110,10 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, podSpec := &deploy.Spec.Template.Spec - podSpec.ServiceAccountName = sa.ObjectMeta.Name - + // sa would be nil when spec.applicationset.enabled = false + if sa != nil { + podSpec.ServiceAccountName = sa.ObjectMeta.Name + } podSpec.Volumes = []corev1.Volume{ { Name: "ssh-known-hosts", @@ -181,7 +183,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, if existing := newDeploymentWithSuffix("applicationset-controller", "controller", cr); argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { - if !cr.Spec.ApplicationSet.IsEnabled() { + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { err := r.Client.Delete(context.TODO(), existing) return err } @@ -425,19 +427,16 @@ func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoproj.ArgoCD) (*v1. if !errors.IsNotFound(err) { return nil, fmt.Errorf("failed to reconcile the role for the service account associated with %s : %s", role.Name, err) } + if errors.IsNotFound(err) && cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil, nil + } if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { return nil, err } - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - err1 := r.Client.Delete(context.TODO(), role) - return nil, err1 - } return role, r.Client.Create(context.TODO(), role) } - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - err := r.Client.Delete(context.TODO(), role) - return nil, err + return nil, r.Client.Delete(context.TODO(), role) } role.Rules = policyRules @@ -458,17 +457,16 @@ func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoproj.ArgoCD roleBindingExists := true if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: roleBinding.Name, Namespace: cr.Namespace}, roleBinding); err != nil { if !errors.IsNotFound(err) { - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - return nil - } return fmt.Errorf("failed to get the rolebinding associated with %s : %s", name, err) } + if errors.IsNotFound(err) && cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil + } roleBindingExists = false } if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - err := r.Client.Delete(context.TODO(), roleBinding) - return err + return r.Client.Delete(context.TODO(), roleBinding) } setAppSetLabels(&roleBinding.ObjectMeta) @@ -563,6 +561,7 @@ func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) er return err } } + return nil } else { if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { return nil // Service found, do nothing diff --git a/controllers/argocd/applicationset_test.go b/controllers/argocd/applicationset_test.go index b022e4cad..65b7f264a 100644 --- a/controllers/argocd/applicationset_test.go +++ b/controllers/argocd/applicationset_test.go @@ -555,6 +555,7 @@ func setProxyEnvVars(t *testing.T) { func TestReconcileApplicationSet_Service(t *testing.T) { logf.SetLogger(ZapLogger(true)) a := makeTestArgoCD() + a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{} resObjs := []client.Object{a} subresObjs := []client.Object{a} diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go index a99d8ecaf..125cd555f 100644 --- a/controllers/argocd/deployment.go +++ b/controllers/argocd/deployment.go @@ -1128,7 +1128,7 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSFor if !cr.Spec.Repo.IsEnabled() { log.Info("Existing ArgoCD Repo Server found but should be disabled. Deleting Repo Server") // Delete existing deployment for ArgoCD Repo Server, if any .. - return nil + return r.Client.Delete(context.TODO(), existing) } changed := false @@ -1328,7 +1328,7 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSF if !cr.Spec.Server.IsEnabled() { log.Info("Existing ArgoCD Server found but should be disabled. Deleting ArgoCD Server") // Delete existing deployment for ArgoCD Server, if any .. - return nil + return r.Client.Delete(context.TODO(), existing) } actualImage := existing.Spec.Template.Spec.Containers[0].Image desiredImage := getArgoContainerImage(cr) @@ -1375,8 +1375,8 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSF return nil // Deployment found with nothing to do, move along... } - if !cr.Spec.Controller.IsEnabled() { - log.Info("ArgoCD Repo Server disabled. Skipping starting repo server.") + if !cr.Spec.Server.IsEnabled() { + log.Info("ArgoCD Server disabled. Skipping starting argocd server.") return nil } diff --git a/controllers/argocd/service.go b/controllers/argocd/service.go index 41ec3fa50..e5123dd95 100644 --- a/controllers/argocd/service.go +++ b/controllers/argocd/service.go @@ -133,13 +133,13 @@ func (r *ReconcileArgoCD) reconcileRedisHAAnnounceServices(cr *argoproj.ArgoCD) for i := int32(0); i < common.ArgoCDDefaultRedisHAReplicas; i++ { svc := newServiceWithSuffix(fmt.Sprintf("redis-ha-announce-%d", i), "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - if !cr.Spec.HA.Enabled { + if !cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return r.Client.Delete(context.TODO(), svc) } return nil // Service found, do nothing } - if !cr.Spec.HA.Enabled { + if !cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return nil //return as Ha is not enabled do nothing } @@ -183,13 +183,13 @@ func (r *ReconcileArgoCD) reconcileRedisHAAnnounceServices(cr *argoproj.ArgoCD) func (r *ReconcileArgoCD) reconcileRedisHAMasterService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("redis-ha", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - if !cr.Spec.HA.Enabled { + if !cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return r.Client.Delete(context.TODO(), svc) } return nil // Service found, do nothing } - if !cr.Spec.HA.Enabled { + if !cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return nil //return as Ha is not enabled do nothing } @@ -222,7 +222,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyService(cr *argoproj.ArgoCD) erro svc := newServiceWithSuffix("redis-ha-haproxy", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - if !cr.Spec.HA.Enabled { + if !cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return r.Client.Delete(context.TODO(), svc) } @@ -232,7 +232,7 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyService(cr *argoproj.ArgoCD) erro return nil // Service found, do nothing } - if !cr.Spec.HA.Enabled { + if !cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return nil //return as Ha is not enabled do nothing } @@ -279,6 +279,9 @@ func (r *ReconcileArgoCD) reconcileRedisService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("redis", "redis", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + if !cr.Spec.Redis.IsEnabled() { + return r.Client.Delete(context.TODO(), svc) + } if ensureAutoTLSAnnotation(svc, common.ArgoCDRedisServerTLSSecretName, cr.Spec.Redis.WantsAutoTLS()) { return r.Client.Update(context.TODO(), svc) } @@ -288,7 +291,7 @@ func (r *ReconcileArgoCD) reconcileRedisService(cr *argoproj.ArgoCD) error { return nil // Service found, do nothing } - if cr.Spec.HA.Enabled { + if cr.Spec.HA.Enabled || !cr.Spec.Redis.IsEnabled() { return nil //return as Ha is enabled do nothing } @@ -358,12 +361,19 @@ func (r *ReconcileArgoCD) reconcileRepoService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("repo-server", "repo-server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + if !cr.Spec.Repo.IsEnabled() { + return r.Client.Delete(context.TODO(), svc) + } if ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) { return r.Client.Update(context.TODO(), svc) } return nil // Service found, do nothing } + if !cr.Spec.Repo.IsEnabled() { + return nil + } + ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) svc.Spec.Selector = map[string]string{ @@ -420,12 +430,19 @@ func (r *ReconcileArgoCD) reconcileServerMetricsService(cr *argoproj.ArgoCD) err func (r *ReconcileArgoCD) reconcileServerService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("server", "server", cr) if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + if !cr.Spec.Server.IsEnabled() { + return r.Client.Delete(context.TODO(), svc) + } if ensureAutoTLSAnnotation(svc, common.ArgoCDServerTLSSecretName, cr.Spec.Server.WantsAutoTLS()) { return r.Client.Update(context.TODO(), svc) } return nil // Service found, do nothing } + if !cr.Spec.Repo.IsEnabled() { + return nil + } + ensureAutoTLSAnnotation(svc, common.ArgoCDServerTLSSecretName, cr.Spec.Server.WantsAutoTLS()) svc.Spec.Ports = []corev1.ServicePort{ diff --git a/controllers/argocd/status.go b/controllers/argocd/status.go index ae7aee3be..46299d641 100644 --- a/controllers/argocd/status.go +++ b/controllers/argocd/status.go @@ -207,7 +207,10 @@ func (r *ReconcileArgoCD) reconcileStatusSSO(cr *argoproj.ArgoCD) error { func (r *ReconcileArgoCD) reconcileStatusPhase(cr *argoproj.ArgoCD) error { var phase string - if cr.Status.ApplicationController == "Running" && cr.Status.Redis == "Running" && cr.Status.Repo == "Running" && cr.Status.Server == "Running" { + if ((!cr.Spec.Controller.IsEnabled() && cr.Status.ApplicationController == "Unknown") || cr.Status.ApplicationController == "Running") && + ((!cr.Spec.Redis.IsEnabled() && cr.Status.Redis == "Unknown") || cr.Status.Redis == "Running") && + ((!cr.Spec.Repo.IsEnabled() && cr.Status.Repo == "Unknown") || cr.Status.Repo == "Running") && + ((!cr.Spec.Server.IsEnabled() && cr.Status.Server == "Unknown") || cr.Status.Server == "Running") { phase = "Available" } else { phase = "Pending" diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-errors.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-errors.yaml new file mode 100644 index 000000000..7c52d27ff --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-errors.yaml @@ -0,0 +1,63 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test + diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-install.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-install.yaml new file mode 100644 index 000000000..81d45d1bf --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/01-install.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: test +--- + +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: false + repo: + enabled: false + server: + enabled: false + applicationSet: + enabled: false \ No newline at end of file diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-assert.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-assert.yaml new file mode 100644 index 000000000..5c885ac3f --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-assert.yaml @@ -0,0 +1,25 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: argocd-test-application-controller + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-argocd-application-controller + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-errors.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-errors.yaml new file mode 100644 index 000000000..b9ddc7108 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-errors.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-repo-server + namespace: test diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-install.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-install.yaml new file mode 100644 index 000000000..7b8bfbc77 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/02-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: true + redis: + enabled: false + repo: + enabled: false + server: + enabled: false + applicationSet: + enabled: false \ No newline at end of file diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-assert.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-assert.yaml new file mode 100644 index 000000000..e8884f5ab --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-assert.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: argocd-test-application-controller + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-argocd-application-controller + namespace: test diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-errors.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-errors.yaml new file mode 100644 index 000000000..8088f7191 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-errors.yaml @@ -0,0 +1,26 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + + + + diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-install.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-install.yaml new file mode 100644 index 000000000..9b756e65a --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/03-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: true + redis: + enabled: true + repo: + enabled: false + server: + enabled: false + applicationSet: + enabled: false \ No newline at end of file diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-assert.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-assert.yaml new file mode 100644 index 000000000..d63df43b4 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-assert.yaml @@ -0,0 +1,42 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test + diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-errors.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-errors.yaml new file mode 100644 index 000000000..0c35367ca --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-errors.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-install.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-install.yaml new file mode 100644 index 000000000..7ada0ebe4 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/04-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: true + redis: + enabled: true + repo: + enabled: true + server: + enabled: false + applicationSet: + enabled: false \ No newline at end of file diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-assert.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-assert.yaml new file mode 100644 index 000000000..7540109ea --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-assert.yaml @@ -0,0 +1,49 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test + diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-errors.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-errors.yaml new file mode 100644 index 000000000..a86fcea4d --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-errors.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-install.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-install.yaml new file mode 100644 index 000000000..6420169e9 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/05-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: true + redis: + enabled: true + repo: + enabled: true + server: + enabled: true + applicationSet: + enabled: false \ No newline at end of file diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-assert.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-assert.yaml new file mode 100644 index 000000000..95ce3a642 --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-assert.yaml @@ -0,0 +1,50 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test + diff --git a/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-install.yaml b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-install.yaml new file mode 100644 index 000000000..f5458f31a --- /dev/null +++ b/tests/k8s/1-034_validate_applicationset_reconcile_enabled_set_false/06-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: true + redis: + enabled: true + repo: + enabled: true + server: + enabled: true + applicationSet: + enabled: true \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-assert.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-assert.yaml new file mode 100644 index 000000000..95ce3a642 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-assert.yaml @@ -0,0 +1,50 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-install.yaml new file mode 100644 index 000000000..9c2d2b5ce --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/01-install.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: test +--- + +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: true + redis: + enabled: true + repo: + enabled: true + server: + enabled: true + applicationSet: + enabled: true \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-assert.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-assert.yaml new file mode 100644 index 000000000..9804b09ea --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-assert.yaml @@ -0,0 +1,41 @@ + +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-argocd-application-controller + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-errors.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-errors.yaml new file mode 100644 index 000000000..db4292f62 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-errors.yaml @@ -0,0 +1,20 @@ + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: argocd-test-application-controller + namespace: test +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-repo-server + namespace: test diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-install.yaml new file mode 100644 index 000000000..eaa19fdbe --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/02-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: true + repo: + enabled: true + server: + enabled: true + applicationSet: + enabled: true \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-assert.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-assert.yaml new file mode 100644 index 000000000..b5b1e6371 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-assert.yaml @@ -0,0 +1,41 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-argocd-application-controller + namespace: test + + + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-errors.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-errors.yaml new file mode 100644 index 000000000..954c88dba --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-errors.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: argocd-test-application-controller + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-install.yaml new file mode 100644 index 000000000..a62670308 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/03-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: false + repo: + enabled: true + server: + enabled: true + applicationSet: + enabled: true \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-assert.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-assert.yaml new file mode 100644 index 000000000..bdbaf6ee8 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-assert.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-errors.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-errors.yaml new file mode 100644 index 000000000..d63abb327 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-errors.yaml @@ -0,0 +1,29 @@ + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test + + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-install.yaml new file mode 100644 index 000000000..98ed44516 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/04-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: false + repo: + enabled: false + server: + enabled: true + applicationSet: + enabled: true \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-assert.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-assert.yaml new file mode 100644 index 000000000..7d9ceeb5a --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-assert.yaml @@ -0,0 +1,27 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +status: + phase: Available +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: argocd-test-argocd-application-controller + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-server + namespace: test + +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: argocd-test-argocd-redis-ha + namespace: test \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-errors.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-errors.yaml new file mode 100644 index 000000000..32a93ab1e --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-errors.yaml @@ -0,0 +1,40 @@ + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test + + + + + + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-install.yaml new file mode 100644 index 000000000..5a3ec51fd --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/05-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: false + repo: + enabled: false + server: + enabled: false + applicationSet: + enabled: true \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-errors.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-errors.yaml new file mode 100644 index 000000000..57b44a981 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-errors.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test + +--- + + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-install.yaml new file mode 100644 index 000000000..c105c5c82 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/06-install.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: false + repo: + enabled: false + server: + enabled: false + applicationSet: + enabled: false \ No newline at end of file diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-errors.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-errors.yaml new file mode 100644 index 000000000..57b44a981 --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-errors.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-redis + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-repo-server + namespace: test + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-server + namespace: test + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: argocd-test-application-controller + namespace: test + +--- + + diff --git a/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-install.yaml b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-install.yaml new file mode 100644 index 000000000..13f4366df --- /dev/null +++ b/tests/k8s/1-035_validate_applicationset_reconcile_enabled_set_true/07-install.yaml @@ -0,0 +1,18 @@ +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: argocd-test + namespace: test +spec: + controller: + enabled: false + redis: + enabled: false + ha: + enabled: true + repo: + enabled: false + server: + enabled: false + applicationSet: + enabled: false \ No newline at end of file From 5166a46490a9f896bc7c6c0a483976ac10c76e11 Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:22:17 +0530 Subject: [PATCH 42/94] docs: enabling/disabling individual argocd core components (#1098) * Add documentation for enabling/disabling argocd core components Signed-off-by: ishitasequeira * rephrase doc Signed-off-by: ishitasequeira * Address comments Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira --- ...abling-disabling-argocd-core-components.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 docs/usage/enabling-disabling-argocd-core-components.md diff --git a/docs/usage/enabling-disabling-argocd-core-components.md b/docs/usage/enabling-disabling-argocd-core-components.md new file mode 100644 index 000000000..ea765a945 --- /dev/null +++ b/docs/usage/enabling-disabling-argocd-core-components.md @@ -0,0 +1,48 @@ +# Enabling/Disabling Core Components of ArgoCD +The Operator oversees all Argo CD workloads, including the API server, repository server, application controller, and more. + +Currently, the following workloads are managed: + +* argocd-server (API server and UI) +* argocd-repo-server (Repository server) +* argocd-application-controller (Main reconciliation controller) +* argocd-applicationset-controller (ApplicationSet reconciliation controller) +* argocd-redis (volatile cache) + +To support installations with minimal resource requirements and to facilitate distribution across clusters or namespaces, the ability to selectively install specific Argo CD components has been introduced. + +To enable/disable a particular Argo CD workload, a new flag, `spec..enabled`, has been implemented. The default value of the flag is `true`, implying that if the flag is unspecified, the Argo CD workload is enabled by default. + +To disable a specific Argo CD component, set the `spec..enabled` flag to `false`. + +Consider the following example: + +```yaml +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: example +spec: + controller: + enabled: false +``` + +In this example, only the controller component is disabled, while all other components continue to run normally. + +# Specifying External URLs for Redis and RepoServer Components +When disabling core components like Redis or Repo Server, you may wish to provide an external URL for components running in external clusters. The remote URL can be set using the `spec..remote` flag (where the component can only be `redis` or `repo`). + +For example, + +```yaml +apiVersion: argoproj.io/v1beta1 +kind: ArgoCD +metadata: + name: example +spec: + repo: + enabled: false + remote: 'https://www.example.com/repo-server' +``` + +!!! Note: The remote flag can only be set if the enabled flag of the component is set to false. \ No newline at end of file From d424ebd71f4d1e67ade00a8b329e3a6e8688950d Mon Sep 17 00:00:00 2001 From: Isaac Gentz Date: Tue, 12 Dec 2023 21:48:32 -0700 Subject: [PATCH 43/94] fix: Proper reference to where to find default admin password (#1094) Signed-off-by: ikegentz --- docs/usage/basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage/basics.md b/docs/usage/basics.md index 1ba43527a..b4d0d0efe 100644 --- a/docs/usage/basics.md +++ b/docs/usage/basics.md @@ -71,7 +71,7 @@ The operator will create these ConfigMaps for the cluster and set the initial va ### Secrets There is a Secret that is used by Argo CD named `argocd-secret`. The `argocd-server` component reads this secret to -obtain the admin password for authentication. +obtain the admin password for authentication. NOTE: Upon initial deployment, the initial password for the `admin` user is stored in the `argocd-cluster` secret instead. This Secret is managed by the operator and should not be changed directly. From f4ba3ff3eae038db09fb01da9a19dfba49ab0cfe Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Mon, 8 Jan 2024 15:08:42 -0500 Subject: [PATCH 44/94] Removed extra constants.go Signed-off-by: Yi Cai --- common/constants.go | 49 --------------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 common/constants.go diff --git a/common/constants.go b/common/constants.go deleted file mode 100644 index 7dc9f6703..000000000 --- a/common/constants.go +++ /dev/null @@ -1,49 +0,0 @@ -package common - -const ( -// // ApplicationController -// ApplicationControllerComponent = "application-controller" -// Done - -// // Notifications -// NotificationsControllerComponent = "notifications-controller" -// NotificationsSecretName = "argocd-notifications-secret" -// NotificationsConfigMapName = "argocd-notifications-cm" -// Done - -// // RepoServer -// RepoServerControllerComponent = "repo-server" -// RepoServerController = "argocd-repo-server" -// RepoServerMetrics = "repo-server-metrics" -// RepoServerTLSSecretName = "argocd-repo-server-tls" -// CopyUtil = "copyutil" -// // Commands -// UidEntryPointSh = "uid_entrypoint.sh" -// ArgoCDRepoServer = "--argocd-repo-server" -// RepoServerTLSRedisCertPath = "/app/config/reposerver/tls/redis/tls.crt" -// // Done - -// // Server -// ServerControllerComponent = "server" -// Done - -// // Redis -// RedisControllerComponent = "redis" -// RedisHAProxyServiceName = "redis-ha-haproxy" -// // Commands -// Redis = "--redis" -// RedisUseTLS = "--redis-use-tls" -// RedisInsecureSkipTLSVerify = "--redis-insecure-skip-tls-verify" -// RedisCACertificate = "--redis-ca-certificate" -// Done - -// // ApplicationSet -// AppSetControllerComponent = "applicationset-controller" -// AppSetController = "argocd-applicationset-controller" -// AppSetGitlabSCMTlsCert = "appset-gitlab-scm-tls-cert" -// AppSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" -// AppSetWebhookRouteName = "applicationset-controller-webhook" -// // Commands -// EntryPointSh = "entrypoint.sh" -// Done -) From acee651b65adc76bb3a7da0bd912bf2eb087811e Mon Sep 17 00:00:00 2001 From: Mangaal <44372157+Mangaal@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:40:11 +0530 Subject: [PATCH 45/94] adding applicationsets in server rbac policy rule (#1140) Signed-off-by: Mangaal --- controllers/argocd/policyrule.go | 1 + 1 file changed, 1 insertion(+) diff --git a/controllers/argocd/policyrule.go b/controllers/argocd/policyrule.go index 641be10e6..276136bf2 100644 --- a/controllers/argocd/policyrule.go +++ b/controllers/argocd/policyrule.go @@ -119,6 +119,7 @@ func policyRuleForServer() []v1.PolicyRule { }, Resources: []string{ "applications", + "applicationsets", "appprojects", }, Verbs: []string{ From 5d6ba7f1e970c28108a1cc11cb58a4a739d9181f Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Wed, 10 Jan 2024 14:30:52 -0500 Subject: [PATCH 46/94] Updated constants following coding standard Signed-off-by: Yi Cai --- common/TOBEREMOVED.go | 3 +++ common/appcontroller.go | 6 ++---- controllers/argocd/appcontroller/constants.go | 5 ----- controllers/argocd/applicationset/deployment.go | 2 +- controllers/argocd/notifications/notifications_test.go | 4 ++-- 5 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 controllers/argocd/appcontroller/constants.go diff --git a/common/TOBEREMOVED.go b/common/TOBEREMOVED.go index 9b90d3c1f..b79bd0712 100644 --- a/common/TOBEREMOVED.go +++ b/common/TOBEREMOVED.go @@ -117,6 +117,9 @@ const ( // ArgoCDNotificationsControllerComponent is the name of the Notifications controller control plane component ArgoCDNotificationsControllerComponent = "argocd-notifications-controller" + + // ArgoCDApplicationControllerComponent is the name of the application controller control plane component + ArgoCDApplicationControllerComponent = "argocd-application-controller" ) // DefaultLabels returns the default set of labels for controllers. diff --git a/common/appcontroller.go b/common/appcontroller.go index e5df572e6..8cd4a23df 100644 --- a/common/appcontroller.go +++ b/common/appcontroller.go @@ -2,8 +2,8 @@ package common // app-controller const ( - // ArgoCDApplicationControllerComponent is the name of the application controller control plane component - ArgoCDApplicationControllerComponent = "argocd-application-controller" + // ApplicationControllerComponent is the name of the application controller control plane component + ApplicationControllerComponent = "application-controller" // ArgoCDApplicationControllerDefaultShardReplicas is the default number of replicas that the ArgoCD Application Controller Should Use ArgocdApplicationControllerDefaultReplicas = 1 @@ -26,6 +26,4 @@ const ( // ArgoCDDefaultControllerResourceRequestMemory is the default memory requested when not specified for the Argo CD // application controller contianer. ArgoCDDefaultControllerResourceRequestMemory = "32Mi" - - ApplicationControllerComponent = "application-controller" ) diff --git a/controllers/argocd/appcontroller/constants.go b/controllers/argocd/appcontroller/constants.go deleted file mode 100644 index 46bfdfdea..000000000 --- a/controllers/argocd/appcontroller/constants.go +++ /dev/null @@ -1,5 +0,0 @@ -package appcontroller - -const ( - ArgoCDApplicationControllerComponent = "application-controller" -) diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 632043424..925221740 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -208,7 +208,7 @@ func (asr *ApplicationSetReconciler) getApplicationSetContainer(addSCMGitlabVolu Command: asr.getApplicationSetCommand(), Image: argocdcommon.GetArgoContainerImage(asr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: common.AppSetController, + Name: resourceName, Env: appSetEnv, Resources: asr.getApplicationSetResources(), SecurityContext: &corev1.SecurityContext{ diff --git a/controllers/argocd/notifications/notifications_test.go b/controllers/argocd/notifications/notifications_test.go index c20331b2d..14e3f6954 100644 --- a/controllers/argocd/notifications/notifications_test.go +++ b/controllers/argocd/notifications/notifications_test.go @@ -14,14 +14,14 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" ) -var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.ArgoCDNotificationsControllerComponent) +var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.NotificationsControllerComponent) func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *NotificationsReconciler { s := scheme.Scheme assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(common.ArgoCDNotificationsControllerComponent) + logger := ctrl.Log.WithName(common.NotificationsControllerComponent) return &NotificationsReconciler{ Client: cl, From d0f5fe3e72ca53bb640cd17c94ccb4b0de91502f Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 14 Jan 2024 08:13:51 -0500 Subject: [PATCH 47/94] remove extra argoutils Signed-off-by: Jaideep Rao --- controllers/argoutil/resource.go | 124 ------------------------------- controllers/argoutil/secret.go | 68 ----------------- 2 files changed, 192 deletions(-) delete mode 100644 controllers/argoutil/resource.go delete mode 100644 controllers/argoutil/secret.go diff --git a/controllers/argoutil/resource.go b/controllers/argoutil/resource.go deleted file mode 100644 index b5adada0f..000000000 --- a/controllers/argoutil/resource.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2019 ArgoCD Operator Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package argoutil - -import ( - "context" - "fmt" - "strings" - - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" -) - -// AppendStringMap will append the map `add` to the given map `src` and return the result. -func AppendStringMap(src map[string]string, add map[string]string) map[string]string { - res := src - if len(src) <= 0 { - res = make(map[string]string, len(add)) - } - for key, val := range add { - res[key] = val - } - return res -} - -// CombineImageTag will return the combined image and tag in the proper format for tags and digests. -func CombineImageTag(img string, tag string) string { - if strings.Contains(tag, ":") { - return fmt.Sprintf("%s@%s", img, tag) // Digest - } else if len(tag) > 0 { - return fmt.Sprintf("%s:%s", img, tag) // Tag - } - return img // No tag, use default -} - -// CreateEvent will create a new Kubernetes Event with the given action, message, reason and involved uid. -func CreateEvent(client client.Client, eventType, action, message, reason string, objectMeta metav1.ObjectMeta, typeMeta metav1.TypeMeta) error { - event := newEvent(objectMeta) - event.Action = action - event.Type = eventType - event.InvolvedObject = corev1.ObjectReference{ - Name: objectMeta.Name, - Namespace: objectMeta.Namespace, - UID: objectMeta.UID, - ResourceVersion: objectMeta.ResourceVersion, - Kind: typeMeta.Kind, - APIVersion: typeMeta.APIVersion, - } - event.Message = message - event.Reason = reason - event.CreationTimestamp = metav1.Now() - event.FirstTimestamp = event.CreationTimestamp - event.LastTimestamp = event.CreationTimestamp - return client.Create(context.TODO(), event) -} - -// FetchObject will retrieve the object with the given namespace and name using the Kubernetes API. -// The result will be stored in the given object. -func FetchObject(client client.Client, namespace string, name string, obj client.Object) error { - return client.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: name}, obj) -} - -// FetchStorageSecretName will return the name of the Secret to use for the export process. -func FetchStorageSecretName(export *argoprojv1alpha1.ArgoCDExport) string { - name := NameWithSuffix(export.ObjectMeta, "export") - if export.Spec.Storage != nil && len(export.Spec.Storage.SecretName) > 0 { - name = export.Spec.Storage.SecretName - } - return name -} - -// IsObjectFound will perform a basic check that the given object exists via the Kubernetes API. -// If an error occurs as part of the check, the function will return false. -func IsObjectFound(client client.Client, namespace string, name string, obj client.Object) bool { - return !apierrors.IsNotFound(FetchObject(client, namespace, name, obj)) -} - -// NameWithSuffix will return a string using the Name from the given ObjectMeta with the provded suffix appended. -// Example: If ObjectMeta.Name is "test" and suffix is "object", the value of "test-object" will be returned. -func NameWithSuffix(meta metav1.ObjectMeta, suffix string) string { - return fmt.Sprintf("%s-%s", meta.Name, suffix) -} - -func newEvent(meta metav1.ObjectMeta) *corev1.Event { - event := &corev1.Event{} - event.ObjectMeta.GenerateName = fmt.Sprintf("%s-", meta.Name) - event.ObjectMeta.Labels = meta.Labels - event.ObjectMeta.Namespace = meta.Namespace - return event -} - -// LabelsForCluster returns the labels for all cluster resources. -func LabelsForCluster(cr *argoproj.ArgoCD) map[string]string { - labels := common.DefaultLabels(cr.Name) - return labels -} - -// annotationsForCluster returns the annotations for all cluster resources. -func AnnotationsForCluster(cr *argoproj.ArgoCD) map[string]string { - annotations := common.DefaultAnnotations(cr.Name, cr.Namespace) - for key, val := range cr.ObjectMeta.Annotations { - annotations[key] = val - } - return annotations -} diff --git a/controllers/argoutil/secret.go b/controllers/argoutil/secret.go deleted file mode 100644 index 7ed01ee91..000000000 --- a/controllers/argoutil/secret.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2019 ArgoCD Operator Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package argoutil - -import ( - "fmt" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" -) - -// FetchSecret will retrieve the object with the given Name using the provided client. -// The result will be returned. -func FetchSecret(client client.Client, meta metav1.ObjectMeta, name string) (*corev1.Secret, error) { - a := &argoproj.ArgoCD{} - a.ObjectMeta = meta - secret := NewSecretWithName(a, name) - return secret, FetchObject(client, meta.Namespace, name, secret) -} - -// NewTLSSecret returns a new TLS Secret based on the given metadata with the provided suffix on the Name. -func NewTLSSecret(cr *argoproj.ArgoCD, suffix string) *corev1.Secret { - secret := NewSecretWithSuffix(cr, suffix) - secret.Type = corev1.SecretTypeTLS - return secret -} - -// NewSecret returns a new Secret based on the given metadata. -func NewSecret(cr *argoproj.ArgoCD) *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Labels: LabelsForCluster(cr), - }, - Type: corev1.SecretTypeOpaque, - } -} - -// NewSecretWithName returns a new Secret based on the given metadata with the provided Name. -func NewSecretWithName(cr *argoproj.ArgoCD, name string) *corev1.Secret { - secret := NewSecret(cr) - - secret.ObjectMeta.Name = name - secret.ObjectMeta.Namespace = cr.Namespace - secret.ObjectMeta.Labels[common.ArgoCDKeyName] = name - - return secret -} - -// NewSecretWithSuffix returns a new Secret based on the given metadata with the provided suffix on the Name. -func NewSecretWithSuffix(cr *argoproj.ArgoCD, suffix string) *corev1.Secret { - return NewSecretWithName(cr, fmt.Sprintf("%s-%s", cr.Name, suffix)) -} From 3da63230673a035d4ea9420e7ad7a27bf6a7953c Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 14 Jan 2024 13:47:28 -0500 Subject: [PATCH 48/94] add mutation args, instance ref, openshift mutations Signed-off-by: Jaideep Rao --- pkg/cluster/event.go | 8 ++- pkg/cluster/namespace.go | 10 +++- pkg/cluster/namespace_test.go | 4 +- pkg/monitoring/monitoring_test.go | 4 +- pkg/monitoring/prometheusRule.go | 11 +++- pkg/monitoring/serviceMonitor.go | 10 +++- pkg/mutation/mutation.go | 6 +- pkg/networking/ingress.go | 10 +++- pkg/networking/networking_test.go | 4 +- pkg/networking/service.go | 11 +++- pkg/openshift/mutation.go | 86 ++++++++++++++++++++++++++++- pkg/openshift/networking.go | 10 +++- pkg/openshift/openshift_test.go | 4 +- pkg/openshift/workloads.go | 10 +++- pkg/permissions/clusterrole.go | 8 ++- pkg/permissions/permissions_test.go | 4 +- pkg/permissions/role.go | 10 +++- pkg/workloads/configmap.go | 10 +++- pkg/workloads/deployment.go | 10 +++- pkg/workloads/hpa.go | 10 +++- pkg/workloads/secret.go | 10 +++- pkg/workloads/statefulset.go | 11 +++- pkg/workloads/workloads_test.go | 4 +- 23 files changed, 205 insertions(+), 60 deletions(-) diff --git a/pkg/cluster/event.go b/pkg/cluster/event.go index ee3f082eb..3a1b4f343 100644 --- a/pkg/cluster/event.go +++ b/pkg/cluster/event.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -23,10 +24,13 @@ type EventRequest struct { CreationTimestamp metav1.Time FirstTimestamp metav1.Time LastTimestamp metav1.Time + Instance *argoproj.ArgoCD // array of functions to mutate event before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } func newEvent(objMeta metav1.ObjectMeta, typeMeta metav1.TypeMeta, eventType, action, message, reason string) *corev1.Event { @@ -61,7 +65,7 @@ func RequestEvent(request EventRequest) (*corev1.Event, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, event, request.Client) + err := mutation(request.Instance, event, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/cluster/namespace.go b/pkg/cluster/namespace.go index e0a536bbd..79520748f 100644 --- a/pkg/cluster/namespace.go +++ b/pkg/cluster/namespace.go @@ -10,6 +10,7 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/mutation" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -17,10 +18,13 @@ import ( type NamespaceRequest struct { ObjectMeta metav1.ObjectMeta Spec corev1.NamespaceSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } func newNamespace(objMeta metav1.ObjectMeta, spec corev1.NamespaceSpec) *corev1.Namespace { @@ -40,7 +44,7 @@ func RequestNamespace(request NamespaceRequest) (*corev1.Namespace, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, namespace, request.Client) + err := mutation(request.Instance, namespace, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/cluster/namespace_test.go b/pkg/cluster/namespace_test.go index 63544f950..d8c3a6b96 100644 --- a/pkg/cluster/namespace_test.go +++ b/pkg/cluster/namespace_test.go @@ -36,11 +36,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { switch obj := resource.(type) { case *corev1.Namespace: if _, ok := obj.Labels[testKey]; ok { diff --git a/pkg/monitoring/monitoring_test.go b/pkg/monitoring/monitoring_test.go index 64ff1e1e2..7d87876c7 100644 --- a/pkg/monitoring/monitoring_test.go +++ b/pkg/monitoring/monitoring_test.go @@ -26,11 +26,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { switch obj := resource.(type) { case *monitoringv1.PrometheusRule: obj.Name = testPrometheusRuleNameMutated diff --git a/pkg/monitoring/prometheusRule.go b/pkg/monitoring/prometheusRule.go index c4f717932..dc5a43028 100644 --- a/pkg/monitoring/prometheusRule.go +++ b/pkg/monitoring/prometheusRule.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -18,9 +19,13 @@ type PrometheusRuleRequest struct { ObjectMeta metav1.ObjectMeta Spec monitoringv1.PrometheusRuleSpec - // array of functions to mutate role before returning to requester + Instance *argoproj.ArgoCD + + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newPrometheusRule returns a new PrometheusRule instance for the given ArgoCD. @@ -89,7 +94,7 @@ func RequestPrometheusRule(request PrometheusRuleRequest) (*monitoringv1.Prometh if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, prometheusRule, request.Client) + err := mutation(request.Instance, prometheusRule, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/monitoring/serviceMonitor.go b/pkg/monitoring/serviceMonitor.go index ffc35794f..a9280eb9a 100644 --- a/pkg/monitoring/serviceMonitor.go +++ b/pkg/monitoring/serviceMonitor.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type ServiceMonitorRequest struct { ObjectMeta metav1.ObjectMeta Spec monitoringv1.ServiceMonitorSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newServiceMonitor returns a new ServiceMonitor instance for the given ArgoCD. @@ -89,7 +93,7 @@ func RequestServiceMonitor(request ServiceMonitorRequest) (*monitoringv1.Service if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, serviceMonitor, request.Client) + err := mutation(request.Instance, serviceMonitor, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/mutation/mutation.go b/pkg/mutation/mutation.go index 24c32a6cf..dc4bbadc7 100644 --- a/pkg/mutation/mutation.go +++ b/pkg/mutation/mutation.go @@ -14,7 +14,7 @@ var ( ) // MutateFunc defines the function signature for any mutation functions that need to be executed by this package -type MutateFunc func(*argoproj.ArgoCD, interface{}, client.Client) error +type MutateFunc func(*argoproj.ArgoCD, interface{}, client.Client, ...interface{}) error // Register adds a modifier for updating resources during reconciliation. func Register(m ...MutateFunc) { @@ -23,11 +23,11 @@ func Register(m ...MutateFunc) { mutateFuncs = append(mutateFuncs, m...) } -func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client client.Client) error { +func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client client.Client, extra ...interface{}) error { mutex.Lock() defer mutex.Unlock() for _, mutateFunc := range mutateFuncs { - if err := mutateFunc(cr, resource, client); err != nil { + if err := mutateFunc(cr, resource, client, extra); err != nil { return err } } diff --git a/pkg/networking/ingress.go b/pkg/networking/ingress.go index c2c2b7f2b..b87bacf1f 100644 --- a/pkg/networking/ingress.go +++ b/pkg/networking/ingress.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type IngressRequest struct { ObjectMeta metav1.ObjectMeta Spec networkingv1.IngressSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newIngress returns a new Ingress instance for the given ArgoCD. @@ -89,7 +93,7 @@ func RequestIngress(request IngressRequest) (*networkingv1.Ingress, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, ingress, request.Client) + err := mutation(request.Instance, ingress, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/networking/networking_test.go b/pkg/networking/networking_test.go index 3aaaa37a9..af3f65ea9 100644 --- a/pkg/networking/networking_test.go +++ b/pkg/networking/networking_test.go @@ -30,11 +30,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { switch obj := resource.(type) { case *corev1.Service: obj.Name = testServiceNameMutated diff --git a/pkg/networking/service.go b/pkg/networking/service.go index d90c2a8eb..02ddda244 100644 --- a/pkg/networking/service.go +++ b/pkg/networking/service.go @@ -11,16 +11,21 @@ import ( cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) // ServiceRequest objects contain all the required information to produce a service object in return type ServiceRequest struct { ObjectMeta metav1.ObjectMeta Spec corev1.ServiceSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newService returns a new Service instance for the given ArgoCD. @@ -89,7 +94,7 @@ func RequestService(request ServiceRequest) (*corev1.Service, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, service, request.Client) + err := mutation(request.Instance, service, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/openshift/mutation.go b/pkg/openshift/mutation.go index 20f1728e2..0cba61d5f 100644 --- a/pkg/openshift/mutation.go +++ b/pkg/openshift/mutation.go @@ -8,22 +8,62 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/pkg/errors" + rbacv1 "k8s.io/api/rbac/v1" ) func init() { mutation.Register(AddSeccompProfileForOpenShift) + mutation.Register(AddNonRootSCCForOpenShift) + mutation.Register(AddAutoTLSAnnotationForOpenShift) } -func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client) error { +// TO DO: Add dedicated e2e tests for all these mutations + +// AddAutoTLSAnnotationForOpenShift adds the OpenShift Service CA TLS cert request annotaiton to the provided service object, using the provided secret name as the value +func AddAutoTLSAnnotationForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { + if !IsOpenShiftEnv() { + return nil + } + switch obj := resource.(type) { + case *corev1.Service: + // return if autoTLS is not requested + if !cr.Spec.Redis.WantsAutoTLS() { + return nil + } + + if obj.Annotations == nil { + obj.Annotations = make(map[string]string) + } + + // there should only be one extra parameter of type string, which would be the name of the TLS secret to be used in the annotation. + // Check to make sure length and type of extra argument match before using this as the secret name + if len(args) == 1 { + for _, arg := range args { + switch val := arg.(type) { + case string: + obj.Annotations[common.ServiceBetaOpenshiftKeyCertSecret] = val + } + } + } + } + return nil +} + +func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { if !IsOpenShiftEnv() { return nil } switch obj := resource.(type) { case *corev1.PodSpec: + if !IsVersionAPIAvailable() { + return nil + } version, err := GetClusterVersion(client) if err != nil { - return err + return errors.Wrapf(err, "AddSeccompProfileForOpenShift: failed to retrieve OpenShift cluster version") } if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 { if obj.SecurityContext == nil { @@ -39,3 +79,45 @@ func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, cl } return nil } + +func AddNonRootSCCForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { + if !IsOpenShiftEnv() { + return nil + } + switch obj := resource.(type) { + case *rbacv1.Role: + // This mutation only applies to redis and redis-ha roles + if component, ok := obj.Labels[common.AppK8sKeyComponent]; !ok || (ok && component != common.ArgoCDRedisComponent) { + return nil + } + + if !IsVersionAPIAvailable() { + return nil + } + version, err := GetClusterVersion(client) + if err != nil { + return errors.Wrapf(err, "AppendNonRootSCCForOpenShift: failed to retrieve OpenShift cluster version") + } + // Starting with OpenShift 4.11, we need to use the resource name "nonroot-v2" instead of "nonroot" + resourceName := "nonroot" + if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 { + orules := rbacv1.PolicyRule{ + APIGroups: []string{ + "security.openshift.io", + }, + ResourceNames: []string{ + resourceName, + }, + Resources: []string{ + "securitycontextconstraints", + }, + Verbs: []string{ + "use", + }, + } + obj.Rules = append(obj.Rules, orules) + } + } + + return nil +} diff --git a/pkg/openshift/networking.go b/pkg/openshift/networking.go index 0e6ffc492..2e0ff13be 100644 --- a/pkg/openshift/networking.go +++ b/pkg/openshift/networking.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -40,10 +41,13 @@ func VerifyRouteAPI() error { type RouteRequest struct { ObjectMeta metav1.ObjectMeta Spec routev1.RouteSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newRoute returns a new Route instance for the given ArgoCD. @@ -112,7 +116,7 @@ func RequestRoute(request RouteRequest) (*routev1.Route, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, route, request.Client) + err := mutation(request.Instance, route, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/openshift/openshift_test.go b/pkg/openshift/openshift_test.go index 7f8cb67af..20ffd67aa 100644 --- a/pkg/openshift/openshift_test.go +++ b/pkg/openshift/openshift_test.go @@ -27,11 +27,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { switch obj := resource.(type) { case *oappsv1.DeploymentConfig: obj.Name = testNameMutated diff --git a/pkg/openshift/workloads.go b/pkg/openshift/workloads.go index 7f757aa94..66100dfec 100644 --- a/pkg/openshift/workloads.go +++ b/pkg/openshift/workloads.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type DeploymentConfigRequest struct { ObjectMeta metav1.ObjectMeta Spec oappsv1.DeploymentConfigSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newDeploymentConfig returns a new DeploymentConfig instance for the given ArgoCD. @@ -88,7 +92,7 @@ func RequestDeploymentConfig(request DeploymentConfigRequest) (*oappsv1.Deployme deploymentConfig := newDeploymentConfig(request.ObjectMeta, request.Spec) if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, deploymentConfig, request.Client) + err := mutation(request.Instance, deploymentConfig, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/permissions/clusterrole.go b/pkg/permissions/clusterrole.go index bce669e3b..3ed043b79 100644 --- a/pkg/permissions/clusterrole.go +++ b/pkg/permissions/clusterrole.go @@ -9,6 +9,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -16,10 +17,13 @@ import ( type ClusterRoleRequest struct { ObjectMeta metav1.ObjectMeta Rules []rbacv1.PolicyRule + Instance *argoproj.ArgoCD // array of functions to mutate clusterRole before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newClusterRole returns a new clusterRole instance. @@ -41,7 +45,7 @@ func RequestClusterRole(request ClusterRoleRequest) (*rbacv1.ClusterRole, error) if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, clusterRole, request.Client) + err := mutation(request.Instance, clusterRole, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/permissions/permissions_test.go b/pkg/permissions/permissions_test.go index 5bfc8ceb6..af65ccfaa 100644 --- a/pkg/permissions/permissions_test.go +++ b/pkg/permissions/permissions_test.go @@ -62,11 +62,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { switch obj := resource.(type) { case *rbacv1.Role: if obj.Namespace == testNamespace { diff --git a/pkg/permissions/role.go b/pkg/permissions/role.go index 28dd60040..90100a5a5 100644 --- a/pkg/permissions/role.go +++ b/pkg/permissions/role.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type RoleRequest struct { ObjectMeta metav1.ObjectMeta Rules []rbacv1.PolicyRule + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newRole returns a new Role instance. @@ -41,7 +45,7 @@ func RequestRole(request RoleRequest) (*rbacv1.Role, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, role, request.Client) + err := mutation(request.Instance, role, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/configmap.go b/pkg/workloads/configmap.go index 992dfdee7..39c4538e7 100644 --- a/pkg/workloads/configmap.go +++ b/pkg/workloads/configmap.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type ConfigMapRequest struct { ObjectMeta metav1.ObjectMeta Data map[string]string + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newConfigMap returns a new ConfigMap instance for the given ArgoCD. @@ -89,7 +93,7 @@ func RequestConfigMap(request ConfigMapRequest) (*corev1.ConfigMap, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, configMap, request.Client) + err := mutation(request.Instance, configMap, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/deployment.go b/pkg/workloads/deployment.go index 692034a48..058b410e6 100644 --- a/pkg/workloads/deployment.go +++ b/pkg/workloads/deployment.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type DeploymentRequest struct { ObjectMeta metav1.ObjectMeta Spec appsv1.DeploymentSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newDeployment returns a new Deployment instance for the given ArgoCD. @@ -90,7 +94,7 @@ func RequestDeployment(request DeploymentRequest) (*appsv1.Deployment, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, deployment, request.Client) + err := mutation(request.Instance, deployment, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/hpa.go b/pkg/workloads/hpa.go index 577898df4..af6454851 100644 --- a/pkg/workloads/hpa.go +++ b/pkg/workloads/hpa.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,10 +18,13 @@ import ( type HorizontalPodAutoscalerRequest struct { ObjectMeta metav1.ObjectMeta Spec autoscaling.HorizontalPodAutoscalerSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newHorizontalPodAutoscaler returns a new HorizontalPodAutoscaler instance for the given ArgoCD. @@ -90,7 +94,7 @@ func RequestHorizontalPodAutoscaler(request HorizontalPodAutoscalerRequest) (*au if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, horizontalPodAutoscaler, request.Client) + err := mutation(request.Instance, horizontalPodAutoscaler, request.Client, request.MutationArgs, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/secret.go b/pkg/workloads/secret.go index 06fa838cf..034a3e68f 100644 --- a/pkg/workloads/secret.go +++ b/pkg/workloads/secret.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" corev1 "k8s.io/api/core/v1" @@ -19,10 +20,13 @@ type SecretRequest struct { Data map[string][]byte StringData map[string]string Type corev1.SecretType + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newSecret returns a new Secret instance for the given ArgoCD. @@ -93,7 +97,7 @@ func RequestSecret(request SecretRequest) (*corev1.Secret, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, secret, request.Client) + err := mutation(request.Instance, secret, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/statefulset.go b/pkg/workloads/statefulset.go index 4ccde760b..0cc4f4bef 100644 --- a/pkg/workloads/statefulset.go +++ b/pkg/workloads/statefulset.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -17,9 +18,13 @@ import ( type StatefulSetRequest struct { ObjectMeta metav1.ObjectMeta Spec appsv1.StatefulSetSpec - // array of functions to mutate role before returning to requester + Instance *argoproj.ArgoCD + + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newStateful returns a new Stateful instance for the given ArgoCD. @@ -89,7 +94,7 @@ func RequestStatefulSet(request StatefulSetRequest) (*appsv1.StatefulSet, error) if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, StatefulSet, request.Client) + err := mutation(request.Instance, StatefulSet, request.Client, request.MutationArgs, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/workloads_test.go b/pkg/workloads/workloads_test.go index fe9a50ed7..244bf96a6 100644 --- a/pkg/workloads/workloads_test.go +++ b/pkg/workloads/workloads_test.go @@ -33,11 +33,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { switch obj := resource.(type) { case *appsv1.Deployment: obj.Name = testNameMutated From cffcbf284677d811ee33c31bb5904c2fcf89ecc7 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 14 Jan 2024 13:53:18 -0500 Subject: [PATCH 49/94] change references Signed-off-by: Jaideep Rao --- pkg/cluster/namespace_test.go | 4 ++-- pkg/monitoring/monitoring_test.go | 4 ++-- pkg/mutation/mutation.go | 4 ++-- pkg/networking/networking_test.go | 4 ++-- pkg/openshift/openshift_test.go | 4 ++-- pkg/permissions/permissions_test.go | 4 ++-- pkg/workloads/workloads_test.go | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/cluster/namespace_test.go b/pkg/cluster/namespace_test.go index d8c3a6b96..00035c195 100644 --- a/pkg/cluster/namespace_test.go +++ b/pkg/cluster/namespace_test.go @@ -36,11 +36,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *corev1.Namespace: if _, ok := obj.Labels[testKey]; ok { diff --git a/pkg/monitoring/monitoring_test.go b/pkg/monitoring/monitoring_test.go index 7d87876c7..834b1c34c 100644 --- a/pkg/monitoring/monitoring_test.go +++ b/pkg/monitoring/monitoring_test.go @@ -26,11 +26,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *monitoringv1.PrometheusRule: obj.Name = testPrometheusRuleNameMutated diff --git a/pkg/mutation/mutation.go b/pkg/mutation/mutation.go index dc4bbadc7..9ea9bf2a9 100644 --- a/pkg/mutation/mutation.go +++ b/pkg/mutation/mutation.go @@ -23,11 +23,11 @@ func Register(m ...MutateFunc) { mutateFuncs = append(mutateFuncs, m...) } -func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client client.Client, extra ...interface{}) error { +func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { mutex.Lock() defer mutex.Unlock() for _, mutateFunc := range mutateFuncs { - if err := mutateFunc(cr, resource, client, extra); err != nil { + if err := mutateFunc(cr, resource, client, args); err != nil { return err } } diff --git a/pkg/networking/networking_test.go b/pkg/networking/networking_test.go index af3f65ea9..449fc36f8 100644 --- a/pkg/networking/networking_test.go +++ b/pkg/networking/networking_test.go @@ -30,11 +30,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *corev1.Service: obj.Name = testServiceNameMutated diff --git a/pkg/openshift/openshift_test.go b/pkg/openshift/openshift_test.go index 20ffd67aa..e6aebd238 100644 --- a/pkg/openshift/openshift_test.go +++ b/pkg/openshift/openshift_test.go @@ -27,11 +27,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *oappsv1.DeploymentConfig: obj.Name = testNameMutated diff --git a/pkg/permissions/permissions_test.go b/pkg/permissions/permissions_test.go index af65ccfaa..f3b920f57 100644 --- a/pkg/permissions/permissions_test.go +++ b/pkg/permissions/permissions_test.go @@ -62,11 +62,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *rbacv1.Role: if obj.Namespace == testNamespace { diff --git a/pkg/workloads/workloads_test.go b/pkg/workloads/workloads_test.go index 244bf96a6..ff378ab8b 100644 --- a/pkg/workloads/workloads_test.go +++ b/pkg/workloads/workloads_test.go @@ -33,11 +33,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, extra ...interface{}) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *appsv1.Deployment: obj.Name = testNameMutated From 816c053f5d79c2f4b4a1c754c253833a5a25f972 Mon Sep 17 00:00:00 2001 From: Anand Kumar Singh Date: Wed, 17 Jan 2024 17:33:49 +0530 Subject: [PATCH 50/94] fix logic to allow processor operation to be less than default value (#1146) * fix logic to allow operation processors to be less than default value --------- Signed-off-by: Anand Kumar Singh --- controllers/argocd/util.go | 2 +- controllers/argocd/util_test.go | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index 8c093fcf4..fb822f6ee 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -309,7 +309,7 @@ func (r *ReconcileArgoCD) getArgoServerURI(cr *argoproj.ArgoCD) string { // getArgoServerOperationProcessors will return the numeric Operation Processors value for the ArgoCD Server. func getArgoServerOperationProcessors(cr *argoproj.ArgoCD) int32 { op := common.ArgoCDDefaultServerOperationProcessors - if cr.Spec.Controller.Processors.Operation > op { + if cr.Spec.Controller.Processors.Operation > 0 { op = cr.Spec.Controller.Processors.Operation } return op diff --git a/controllers/argocd/util_test.go b/controllers/argocd/util_test.go index 019b2c442..daeeb11aa 100644 --- a/controllers/argocd/util_test.go +++ b/controllers/argocd/util_test.go @@ -389,6 +389,48 @@ func TestGetArgoApplicationControllerCommand(t *testing.T) { "text", }, }, + { + "configured operation processors to zero", + []argoCDOpt{operationProcessors(0)}, + []string{ + "argocd-application-controller", + "--operation-processors", + "10", + "--redis", + "argocd-redis.argocd.svc.cluster.local:6379", + "--repo-server", + "argocd-repo-server.argocd.svc.cluster.local:8081", + "--status-processors", + "20", + "--kubectl-parallelism-limit", + "10", + "--loglevel", + "info", + "--logformat", + "text", + }, + }, + { + "configured operation processors to be between zero and ten", + []argoCDOpt{operationProcessors(5)}, + []string{ + "argocd-application-controller", + "--operation-processors", + "5", + "--redis", + "argocd-redis.argocd.svc.cluster.local:6379", + "--repo-server", + "argocd-repo-server.argocd.svc.cluster.local:8081", + "--status-processors", + "20", + "--kubectl-parallelism-limit", + "10", + "--loglevel", + "info", + "--logformat", + "text", + }, + }, { "configured parallelism limit", []argoCDOpt{parallelismLimit(30)}, From 619229699ea7167cc75bcd738e799ccae12275a3 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Wed, 17 Jan 2024 09:19:28 -0500 Subject: [PATCH 51/94] port mutation changes from redis branch Signed-off-by: Jaideep Rao --- pkg/mutation/mutation.go | 2 +- pkg/networking/service.go | 2 +- pkg/openshift/mutation.go | 102 +++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/pkg/mutation/mutation.go b/pkg/mutation/mutation.go index 9ea9bf2a9..307db7746 100644 --- a/pkg/mutation/mutation.go +++ b/pkg/mutation/mutation.go @@ -27,7 +27,7 @@ func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client c mutex.Lock() defer mutex.Unlock() for _, mutateFunc := range mutateFuncs { - if err := mutateFunc(cr, resource, client, args); err != nil { + if err := mutateFunc(cr, resource, client, args...); err != nil { return err } } diff --git a/pkg/networking/service.go b/pkg/networking/service.go index ae737cb71..d5b72858a 100644 --- a/pkg/networking/service.go +++ b/pkg/networking/service.go @@ -43,7 +43,7 @@ func RequestService(request ServiceRequest) (*corev1.Service, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(request.Instance, service, request.Client, request.MutationArgs) + err := mutation(request.Instance, service, request.Client, request.MutationArgs...) if err != nil { mutationErr = err } diff --git a/pkg/openshift/mutation.go b/pkg/openshift/mutation.go index 0cba61d5f..20e812b59 100644 --- a/pkg/openshift/mutation.go +++ b/pkg/openshift/mutation.go @@ -11,6 +11,7 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/pkg/errors" + appsv1 "k8s.io/api/apps/v1" rbacv1 "k8s.io/api/rbac/v1" ) @@ -29,6 +30,9 @@ func AddAutoTLSAnnotationForOpenShift(cr *argoproj.ArgoCD, resource interface{}, } switch obj := resource.(type) { case *corev1.Service: + if cr == nil { + return nil + } // return if autoTLS is not requested if !cr.Spec.Redis.WantsAutoTLS() { return nil @@ -38,12 +42,13 @@ func AddAutoTLSAnnotationForOpenShift(cr *argoproj.ArgoCD, resource interface{}, obj.Annotations = make(map[string]string) } - // there should only be one extra parameter of type string, which would be the name of the TLS secret to be used in the annotation. - // Check to make sure length and type of extra argument match before using this as the secret name + // Ensure that args carries only one argument, which is a map of type map[string]string + // containing the key "tls-secret-name". If this is the case, the associated value + // can be used within the service annotation if len(args) == 1 { for _, arg := range args { - switch val := arg.(type) { - case string: + argMap := arg.(map[string]string) + if val, ok := argMap[common.TLSSecretNameKey]; ok { obj.Annotations[common.ServiceBetaOpenshiftKeyCertSecret] = val } } @@ -56,8 +61,8 @@ func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, cl if !IsOpenShiftEnv() { return nil } - switch obj := resource.(type) { - case *corev1.PodSpec: + + addSeccompProfile := func(podSpec *corev1.PodSpec) error { if !IsVersionAPIAvailable() { return nil } @@ -65,17 +70,51 @@ func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, cl if err != nil { return errors.Wrapf(err, "AddSeccompProfileForOpenShift: failed to retrieve OpenShift cluster version") } + if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 { - if obj.SecurityContext == nil { - obj.SecurityContext = &corev1.PodSecurityContext{} + if podSpec.SecurityContext == nil { + podSpec.SecurityContext = &corev1.PodSecurityContext{} + } + if podSpec.SecurityContext.SeccompProfile == nil { + podSpec.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} } - if obj.SecurityContext.SeccompProfile == nil { - obj.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} + if len(podSpec.SecurityContext.SeccompProfile.Type) == 0 { + podSpec.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault } - if len(obj.SecurityContext.SeccompProfile.Type) == 0 { - obj.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault + + containers := []corev1.Container{} + for _, container := range podSpec.Containers { + if container.SecurityContext.SeccompProfile == nil { + container.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} + } + if len(container.SecurityContext.SeccompProfile.Type) == 0 { + container.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault + } + containers = append(containers, container) + } + podSpec.Containers = containers + + initContainers := []corev1.Container{} + for _, initc := range podSpec.InitContainers { + if initc.SecurityContext.SeccompProfile == nil { + initc.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} + } + if len(initc.SecurityContext.SeccompProfile.Type) == 0 { + initc.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault + } + initContainers = append(initContainers, initc) } + podSpec.InitContainers = initContainers + } + return nil + } + + switch obj := resource.(type) { + case *appsv1.StatefulSet: + return addSeccompProfile(&obj.Spec.Template.Spec) + case *appsv1.Deployment: + return addSeccompProfile(&obj.Spec.Template.Spec) } return nil } @@ -87,36 +126,39 @@ func AddNonRootSCCForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client switch obj := resource.(type) { case *rbacv1.Role: // This mutation only applies to redis and redis-ha roles - if component, ok := obj.Labels[common.AppK8sKeyComponent]; !ok || (ok && component != common.ArgoCDRedisComponent) { + if component, ok := obj.Labels[common.AppK8sKeyComponent]; !ok || (ok && component != common.RedisComponent) { return nil } if !IsVersionAPIAvailable() { return nil } + // Starting with OpenShift 4.11, we need to use the resource name "nonroot-v2" instead of "nonroot" + resourceName := "nonroot" version, err := GetClusterVersion(client) if err != nil { return errors.Wrapf(err, "AppendNonRootSCCForOpenShift: failed to retrieve OpenShift cluster version") } - // Starting with OpenShift 4.11, we need to use the resource name "nonroot-v2" instead of "nonroot" - resourceName := "nonroot" + if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 { - orules := rbacv1.PolicyRule{ - APIGroups: []string{ - "security.openshift.io", - }, - ResourceNames: []string{ - resourceName, - }, - Resources: []string{ - "securitycontextconstraints", - }, - Verbs: []string{ - "use", - }, - } - obj.Rules = append(obj.Rules, orules) + resourceName = "nonroot-v2" + } + + orules := rbacv1.PolicyRule{ + APIGroups: []string{ + "security.openshift.io", + }, + ResourceNames: []string{ + resourceName, + }, + Resources: []string{ + "securitycontextconstraints", + }, + Verbs: []string{ + "use", + }, } + obj.Rules = append(obj.Rules, orules) } return nil From 4428be692d8b5a7f788c99f00da2dbe30f95e8f5 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Wed, 17 Jan 2024 10:10:04 -0500 Subject: [PATCH 52/94] port changes to common constants Signed-off-by: Jaideep Rao --- common/TOBEREMOVED.go | 43 ++++++++++++++++++++++ common/envVars.go | 12 ------- common/keys.go | 5 +++ common/redis.go | 83 ++++++++++++++++++++++++++++++------------- common/reposerver.go | 2 ++ common/values.go | 9 +++++ 6 files changed, 118 insertions(+), 36 deletions(-) diff --git a/common/TOBEREMOVED.go b/common/TOBEREMOVED.go index 9b90d3c1f..c6ce3ab01 100644 --- a/common/TOBEREMOVED.go +++ b/common/TOBEREMOVED.go @@ -117,6 +117,49 @@ const ( // ArgoCDNotificationsControllerComponent is the name of the Notifications controller control plane component ArgoCDNotificationsControllerComponent = "argocd-notifications-controller" + + ArgoCDDefaultRedisSuffix = "redis" + + // ArgoCDRedisComponent is the name of the Redis control plane component + ArgoCDRedisComponent = "argocd-redis" + + // ArgoCDRedisHAComponent is the name of the Redis HA control plane component + ArgoCDRedisHAComponent = "argocd-redis-ha" + + // ArgoCDDefaultRedisPort is the default listen port for Redis. + ArgoCDDefaultRedisPort = 6379 + + // ArgoCDDefaultRedisImage is the Redis container image to use when not specified. + ArgoCDDefaultRedisImage = "redis" + + // ArgoCDDefaultRedisSentinelPort is the default listen port for Redis sentinel. + ArgoCDDefaultRedisSentinelPort = 26379 + + // ArgoCDDefaultRedisVersion is the Redis container image tag to use when not specified. + ArgoCDDefaultRedisVersion = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + + // ArgoCDDefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. + ArgoCDDefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + + // ArgoCDDefaultRedisConfigPath is the default Redis configuration directory when not specified. + ArgoCDDefaultRedisConfigPath = "/var/lib/redis" + + // ArgoCDDefaultRedisHAReplicas is the defaul number of replicas for Redis when rinning in HA mode. + ArgoCDDefaultRedisHAReplicas = int32(3) + + // ArgoCDDefaultRedisHAProxyImage is the default Redis HAProxy image to use when not specified. + ArgoCDDefaultRedisHAProxyImage = "haproxy" + + // ArgoCDDefaultRedisHAProxyVersion is the default Redis HAProxy image tag to use when not specified. + ArgoCDDefaultRedisHAProxyVersion = "sha256:7392fbbbb53e9e063ca94891da6656e6062f9d021c0e514888a91535b9f73231" // 2.0.25-alpine + + // ArgoCDRedisHAProxyImageEnvVar is the environment variable used to get the image + // to used for the Redis HA Proxy container. + ArgoCDRedisHAProxyImageEnvVar = "ARGOCD_REDIS_HA_PROXY_IMAGE" + + // ArgoCDRedisHAImageEnvVar is the environment variable used to get the image + // to used for the the Redis container in HA mode. + ArgoCDRedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" ) // DefaultLabels returns the default set of labels for controllers. diff --git a/common/envVars.go b/common/envVars.go index f7e705382..9b8593f28 100644 --- a/common/envVars.go +++ b/common/envVars.go @@ -18,18 +18,6 @@ const ( // to used for the Dex container. ArgoCDRepoImageEnvVar = "ARGOCD_REPOSERVER_IMAGE" - // ArgoCDRedisHAProxyImageEnvVar is the environment variable used to get the image - // to used for the Redis HA Proxy container. - ArgoCDRedisHAProxyImageEnvVar = "ARGOCD_REDIS_HA_PROXY_IMAGE" - - // ArgoCDRedisHAImageEnvVar is the environment variable used to get the image - // to used for the the Redis container in HA mode. - ArgoCDRedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" - - // ArgoCDRedisImageEnvVar is the environment variable used to get the image - // to used for the Redis container. - ArgoCDRedisImageEnvVar = "ARGOCD_REDIS_IMAGE" - // ArgoCDGrafanaImageEnvVar is the environment variable used to get the image // to used for the Grafana container. ArgoCDGrafanaImageEnvVar = "ARGOCD_GRAFANA_IMAGE" diff --git a/common/keys.go b/common/keys.go index 956ece08d..2998bdc37 100644 --- a/common/keys.go +++ b/common/keys.go @@ -208,3 +208,8 @@ const ( // ArgoCDArgoprojKeyManagedByClusterArgoCD is needed to identify namespace mentioned as sourceNamespace on ArgoCD ArgoCDArgoprojKeyManagedByClusterArgoCD = "argocd.argoproj.io/managed-by-cluster-argocd" ) + +// misc +const ( + TLSSecretNameKey = "tls-secret-name" +) diff --git a/common/redis.go b/common/redis.go index 97302fe2c..b687da112 100644 --- a/common/redis.go +++ b/common/redis.go @@ -2,14 +2,12 @@ package common // names const ( - // ArgoCDRedisComponent is the name of the Redis control plane component - ArgoCDRedisComponent = "argocd-redis" + RedisController = "redis-controller" - // ArgoCDRedisHAComponent is the name of the Redis HA control plane component - ArgoCDRedisHAComponent = "argocd-redis-ha" + // RedisComponentName is the Redis control plane component + RedisComponent = "redis" - //ArgoCDDefaultRedisSuffix is the default suffix to use for Redis resources. - ArgoCDDefaultRedisSuffix = "redis" + HAProxyName = "haproxy" // ArgoCDRedisHAConfigMapName is the upstream ArgoCD Redis HA ConfigMap name. ArgoCDRedisHAConfigMapName = "argocd-redis-ha-configmap" @@ -24,33 +22,70 @@ const ( ArgoCDRedisServerTLSSecretName = "argocd-operator-redis-tls" ) -// deafults +// suffixes const ( + //RedisSuffix is the default suffix to use for Redis resources. + RedisSuffix = "redis" - // ArgoCDDefaultRedisConfigPath is the default Redis configuration directory when not specified. - ArgoCDDefaultRedisConfigPath = "/var/lib/redis" + RedisHASuffix = "redis-ha" - // ArgoCDDefaultRedisHAReplicas is the defaul number of replicas for Redis when rinning in HA mode. - ArgoCDDefaultRedisHAReplicas = int32(3) + RedisHAProxySuffix = "redis-ha-haproxy" - // ArgoCDDefaultRedisHAProxyImage is the default Redis HAProxy image to use when not specified. - ArgoCDDefaultRedisHAProxyImage = "haproxy" + RedisHAServerSuffix = "redis-ha-server" - // ArgoCDDefaultRedisHAProxyVersion is the default Redis HAProxy image tag to use when not specified. - ArgoCDDefaultRedisHAProxyVersion = "sha256:7392fbbbb53e9e063ca94891da6656e6062f9d021c0e514888a91535b9f73231" // 2.0.25-alpine + RedisHAAnnouceSuffix = "redis-ha-announce" +) + +// defaults +const ( + + // DefaultRedisConfigPath is the default Redis configuration directory when not specified. + DefaultRedisConfigPath = "/var/lib/redis" + + // DefaultRedisHAReplicas is the defaul number of replicas for Redis when rinning in HA mode. + DefaultRedisHAReplicas = int32(3) + + // DefaultRedisHAProxyImage is the default Redis HAProxy image to use when not specified. + DefaultRedisHAProxyImage = "haproxy" + + // DefaultRedisHAProxyVersion is the default Redis HAProxy image tag to use when not specified. + DefaultRedisHAProxyVersion = "sha256:7392fbbbb53e9e063ca94891da6656e6062f9d021c0e514888a91535b9f73231" // 2.0.25-alpine // ArgoCDDefaultRedisImage is the Redis container image to use when not specified. - ArgoCDDefaultRedisImage = "redis" + DefaultRedisImage = "redis" + + // DefaultRedisPort is the default listen port for Redis. + DefaultRedisPort = 6379 - // ArgoCDDefaultRedisPort is the default listen port for Redis. - ArgoCDDefaultRedisPort = 6379 + // DefaultRedisSentinelPort is the default listen port for Redis sentinel. + DefaultRedisSentinelPort = 26379 - // ArgoCDDefaultRedisSentinelPort is the default listen port for Redis sentinel. - ArgoCDDefaultRedisSentinelPort = 26379 + // DefaultRedisVersion is the Redis container image tag to use when not specified. + DefaultRedisVersion = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine - // ArgoCDDefaultRedisVersion is the Redis container image tag to use when not specified. - ArgoCDDefaultRedisVersion = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + // DefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. + DefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine +) + +// env vars +const ( + // RedisHAProxyImageEnvVar is the environment variable used to get the image + // to used for the Redis HA Proxy container. + RedisHAProxyImageEnvVar = "ARGOCD_REDIS_HA_PROXY_IMAGE" + + // RedisHAImageEnvVar is the environment variable used to get the image + // to used for the the Redis container in HA mode. + RedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" - // ArgoCDDefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. - ArgoCDDefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + // RedisImageEnvVar is the environment variable used to get the image + // to used for the Redis container. + RedisImageEnvVar = "ARGOCD_REDIS_IMAGE" + + // RedisConfigPathEnvVar is the environment variiable used to get the redis configuration templates + RedisConfigPathEnvVar = "REDIS_CONFIG_PATH" +) + +// keys +const ( + RedisTLSCertChangedKey = "redis.tls.cert.changed" ) diff --git a/common/reposerver.go b/common/reposerver.go index 51a190700..17575b899 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -4,6 +4,8 @@ package common const ( // ArgoCDRepoServerTLSSecretName is the name of the TLS secret for the repo-server ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" + + RepoServerSuffix = "-repo-server" ) // values diff --git a/common/values.go b/common/values.go index 0747801be..5e3b002be 100644 --- a/common/values.go +++ b/common/values.go @@ -41,6 +41,14 @@ const ( // ArgoCDMetrics is the resource metrics key for labels. ArgoCDMetrics = "metrics" + + ArgoCDStatusUnknown = "Unknown" + + ArgoCDStatusPending = "Pending" + + ArgoCDStatusRunning = "Running" + + ArgoCDStatusAvailable = "Available" ) // general values @@ -75,6 +83,7 @@ const ( SecretKind = "Secret" ServiceKind = "Service" ServiceAccountKind = "ServiceAccount" + ArgoCDKind = "ArgoCD" ) // Commnds From 3c80cd24788ab80862c19d59f749d2805dcb93e4 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Wed, 17 Jan 2024 21:34:52 +0530 Subject: [PATCH 53/94] Use correct repo-server address for notification controller (#1125) Signed-off-by: Siddhesh Ghadi --- controllers/argocd/notifications.go | 6 ++++++ controllers/argocd/notifications_test.go | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/controllers/argocd/notifications.go b/controllers/argocd/notifications.go index 5e0699568..b7baa3ad0 100644 --- a/controllers/argocd/notifications.go +++ b/controllers/argocd/notifications.go @@ -531,6 +531,12 @@ func getNotificationsCommand(cr *argoproj.ArgoCD) []string { cmd = append(cmd, "--loglevel") cmd = append(cmd, getLogLevel(cr.Spec.Notifications.LogLevel)) + if cr.Spec.Repo.IsEnabled() { + cmd = append(cmd, "--argocd-repo-server", getRepoServerAddress(cr)) + } else { + log.Info("Repo Server is disabled. This would affect the functioning of Notification Controller.") + } + return cmd } diff --git a/controllers/argocd/notifications_test.go b/controllers/argocd/notifications_test.go index 11bbd5f18..6418f6fc0 100644 --- a/controllers/argocd/notifications_test.go +++ b/controllers/argocd/notifications_test.go @@ -166,7 +166,7 @@ func TestReconcileNotifications_CreateDeployments(t *testing.T) { assert.Equal(t, deployment.Spec.Template.Spec.ServiceAccountName, sa.ObjectMeta.Name) want := []corev1.Container{{ - Command: []string{"argocd-notifications", "--loglevel", "info"}, + Command: []string{"argocd-notifications", "--loglevel", "info", "--argocd-repo-server", "argocd-repo-server.argocd.svc.cluster.local:8081"}, Image: argoutil.CombineImageTag(common.ArgoCDDefaultArgoImage, common.ArgoCDDefaultArgoVersion), ImagePullPolicy: corev1.PullAlways, Name: "argocd-notifications-controller", @@ -413,6 +413,8 @@ func TestReconcileNotifications_testLogLevel(t *testing.T) { "argocd-notifications", "--loglevel", "debug", + "--argocd-repo-server", + "argocd-repo-server.argocd.svc.cluster.local:8081", } if diff := cmp.Diff(expectedCMD, deployment.Spec.Template.Spec.Containers[0].Command); diff != "" { From 764c29c8bcaeb3bfc7fbe8bc048c6b757488a74b Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Wed, 17 Jan 2024 13:53:12 -0500 Subject: [PATCH 54/94] undo changes to common pkg Signed-off-by: Jaideep Rao --- common/TOBEREMOVED.go | 3 --- common/appcontroller.go | 4 ++-- common/appset.go | 11 ----------- common/envVars.go | 2 -- common/keys.go | 2 -- common/notifications.go | 2 +- common/redis.go | 11 ----------- common/reposerver.go | 13 ------------- common/server.go | 2 -- common/values.go | 42 ++++++++++++++++------------------------- 10 files changed, 19 insertions(+), 73 deletions(-) diff --git a/common/TOBEREMOVED.go b/common/TOBEREMOVED.go index b79bd0712..9b90d3c1f 100644 --- a/common/TOBEREMOVED.go +++ b/common/TOBEREMOVED.go @@ -117,9 +117,6 @@ const ( // ArgoCDNotificationsControllerComponent is the name of the Notifications controller control plane component ArgoCDNotificationsControllerComponent = "argocd-notifications-controller" - - // ArgoCDApplicationControllerComponent is the name of the application controller control plane component - ArgoCDApplicationControllerComponent = "argocd-application-controller" ) // DefaultLabels returns the default set of labels for controllers. diff --git a/common/appcontroller.go b/common/appcontroller.go index 8cd4a23df..6f3abd466 100644 --- a/common/appcontroller.go +++ b/common/appcontroller.go @@ -2,8 +2,8 @@ package common // app-controller const ( - // ApplicationControllerComponent is the name of the application controller control plane component - ApplicationControllerComponent = "application-controller" + // ArgoCDApplicationControllerComponent is the name of the application controller control plane component + ArgoCDApplicationControllerComponent = "argocd-application-controller" // ArgoCDApplicationControllerDefaultShardReplicas is the default number of replicas that the ArgoCD Application Controller Should Use ArgocdApplicationControllerDefaultReplicas = 1 diff --git a/common/appset.go b/common/appset.go index 5f3a0ea22..fa735243c 100644 --- a/common/appset.go +++ b/common/appset.go @@ -7,15 +7,4 @@ const ( //ApplicationSetServiceNameSuffix is the suffix for Apllication Set Controller Service ApplicationSetServiceNameSuffix = "applicationset-controller" - - AppSetControllerComponent = "applicationset-controller" - AppSetController = "argocd-applicationset-controller" - AppSetGitlabSCMTlsCert = "appset-gitlab-scm-tls-cert" - AppSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" - AppSetWebhookRouteName = "applicationset-controller-webhook" -) - -// commands -const ( - EntryPointSh = "entrypoint.sh" ) diff --git a/common/envVars.go b/common/envVars.go index 4b28783d2..f7e705382 100644 --- a/common/envVars.go +++ b/common/envVars.go @@ -44,8 +44,6 @@ const ( // instances ArgoCDClusterConfigNamespacesEnvVar = "ARGOCD_CLUSTER_CONFIG_NAMESPACES" - ArgoCDExecTimeoutEnvVar = "ARGOCD_EXEC_TIMEOUT" - // ArgoCDLabelSelectorEnvVar is an environment variable that contains the labels used for selective instance reconilliation. ArgoCDLabelSelectorEnvVar = "ARGOCD_LABEL_SELECTOR" ) diff --git a/common/keys.go b/common/keys.go index 988ef2b9a..956ece08d 100644 --- a/common/keys.go +++ b/common/keys.go @@ -129,8 +129,6 @@ const ( // ArgoCDDexSecretKey is used to reference Dex secret from Argo CD secret into Argo CD configmap ArgoCDDexSecretKey = "oidc.dex.clientSecret" - - ArgoCDRepoTLSCertChangedKey = "repo.tls.cert.changed" ) // openshift.io keys diff --git a/common/notifications.go b/common/notifications.go index 2b47088e1..dade5a663 100644 --- a/common/notifications.go +++ b/common/notifications.go @@ -2,7 +2,7 @@ package common // notifications const ( - NotificationsControllerComponent = "notifications-controller" + NotificationsControllerComponent = "argocd-notifications-controller" NotificationsSecretName = "argocd-notifications-secret" NotificationsConfigMapName = "argocd-notifications-cm" ) diff --git a/common/redis.go b/common/redis.go index f20080170..97302fe2c 100644 --- a/common/redis.go +++ b/common/redis.go @@ -22,9 +22,6 @@ const ( // ArgoCDRedisServerTLSSecretName is the name of the TLS secret for the redis-server ArgoCDRedisServerTLSSecretName = "argocd-operator-redis-tls" - - RedisControllerComponent = "redis" - RedisHAProxyServiceName = "redis-ha-haproxy" ) // deafults @@ -57,11 +54,3 @@ const ( // ArgoCDDefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. ArgoCDDefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine ) - -// commands -const ( - Redis = "--redis" - RedisUseTLS = "--redis-use-tls" - RedisInsecureSkipTLSVerify = "--redis-insecure-skip-tls-verify" - RedisCACertificate = "--redis-ca-certificate" -) diff --git a/common/reposerver.go b/common/reposerver.go index dc796d92b..51a190700 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -4,12 +4,6 @@ package common const ( // ArgoCDRepoServerTLSSecretName is the name of the TLS secret for the repo-server ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" - - RepoServerControllerComponent = "repo-server" - RepoServerController = "argocd-repo-server" - RepoServerMetrics = "repo-server-metrics" - RepoServerTLSSecretName = "argocd-repo-server-tls" - CopyUtil = "copyutil" ) // values @@ -26,10 +20,3 @@ const ( // ArgoCDDefaultRepoServerPort is the default listen port for the Argo CD repo server. ArgoCDDefaultRepoServerPort = 8081 ) - -// commands -const ( - UidEntryPointSh = "uid_entrypoint.sh" - ArgoCDRepoServer = "--argocd-repo-server" - RepoServerTLSRedisCertPath = "/app/config/reposerver/tls/redis/tls.crt" -) diff --git a/common/server.go b/common/server.go index caf6e4b7d..1b7477a93 100644 --- a/common/server.go +++ b/common/server.go @@ -7,8 +7,6 @@ const ( // ArgoCDServerTLSSecretName is the name of the TLS secret for the argocd-server ArgoCDServerTLSSecretName = "argocd-server-tls" - - ServerControllerComponent = "server" ) // defaults diff --git a/common/values.go b/common/values.go index 6fecc986d..0747801be 100644 --- a/common/values.go +++ b/common/values.go @@ -45,29 +45,21 @@ const ( // general values const ( - TimeFormatMST = "01022006-150406-MST" - TLSCerts = "tls-certs" - CapabilityDropAll = "ALL" - VolumeMountPathRepoServerTLSRedis = "/app/config/reposerver/tls/redis" - VolumeMountPathTLS = "/app/config/tls" - VolumeMountPlugins = "plugins" - VolumeMountPathPlugins = "/home/argocd/cmp-server/plugins" - VolumeVarFiles = "var-files" - VolumeMountPathVarRunArgocd = "/var/run/argocd" - PortWebhook = "webhook" - VolumeMountPathRepoServerTLS = "/app/config/reposerver/tls" - WorkingDirApp = "/app" - Webhook = "webhook" - SSHKnownHosts = "ssh-known-hosts" - VolumeMountPathSSH = "/app/config/ssh" - GPGKeys = "gpg-keys" - VolumeMountPathGPG = "/app/config/gpg/source" - GPGKeyRing = "gpg-keyring" - VolumeMountPathGPGKeyring = "/app/config/gpg/keys" - VolumeTmp = "tmp" - VolumeMountPathTmp = "/tmp" - Server = "server" - OpenShift = "openshift" + TimeFormatMST = "01022006-150406-MST" + TLSCerts = "tls-certs" + CapabilityDropAll = "ALL" + VolumeMountPathTLS = "/app/config/tls" + VolumeMountPathRepoServerTLS = "/app/config/reposerver/tls" + WorkingDirApp = "/app" + Webhook = "webhook" + SSHKnownHosts = "ssh-known-hosts" + VolumeMountPathSSH = "/app/config/ssh" + GPGKeys = "gpg-keys" + VolumeMountPathGPG = "/app/config/gpg/source" + GPGKeyRing = "gpg-keyring" + VolumeMountPathGPGKeyring = "/app/config/gpg/keys" + VolumeTmp = "tmp" + VolumeMountPathTmp = "/tmp" ) // API group versions and resource kinds @@ -83,11 +75,9 @@ const ( SecretKind = "Secret" ServiceKind = "Service" ServiceAccountKind = "ServiceAccount" - StatefulSetKind = "StatefulSet" ) // Commnds const ( - LogLevel = "--loglevel" - LogFormat = "--logformat" + LogLevel = "--loglevel" ) From d9f573554dd4a3af3b908cd16f3d4bbc05049d9e Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Wed, 17 Jan 2024 16:06:53 -0500 Subject: [PATCH 55/94] wip: fix up repo-server Signed-off-by: Jaideep Rao --- .../argocd/applicationset/applicationset.go | 35 +++++++++++-------- .../applicationset/applicationset_test.go | 4 +-- .../argocd/applicationset/constants.go | 14 ++++++++ .../argocd/applicationset/deployment.go | 21 +++++------ .../argocd/applicationset/webhookroute.go | 4 +-- .../applicationset/webhookroute_test.go | 7 ++-- pkg/networking/service.go | 32 ----------------- pkg/workloads/deployment.go | 12 ------- pkg/workloads/statefulset.go | 11 ------ 9 files changed, 50 insertions(+), 90 deletions(-) create mode 100644 controllers/argocd/applicationset/constants.go diff --git a/controllers/argocd/applicationset/applicationset.go b/controllers/argocd/applicationset/applicationset.go index 90420761e..f7e3a7a6f 100644 --- a/controllers/argocd/applicationset/applicationset.go +++ b/controllers/argocd/applicationset/applicationset.go @@ -8,6 +8,7 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + "github.com/argoproj-labs/argocd-operator/pkg/openshift" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) @@ -26,10 +27,10 @@ var ( func (asr *ApplicationSetReconciler) Reconcile() error { - asr.Logger = ctrl.Log.WithName(common.AppSetControllerComponent).WithValues("instance", asr.Instance.Name, "instance-namespace", asr.Instance.Namespace) + asr.Logger = ctrl.Log.WithName(AppSetControllerComponent).WithValues("instance", asr.Instance.Name, "instance-namespace", asr.Instance.Namespace) - resourceName = argoutil.GenerateUniqueResourceName(asr.Instance.Name, asr.Instance.Namespace, common.AppSetControllerComponent) - resourceLabels = common.DefaultResourceLabels(resourceName, asr.Instance.Name, common.AppSetControllerComponent) + resourceName = argoutil.GenerateUniqueResourceName(asr.Instance.Name, asr.Instance.Namespace, AppSetControllerComponent) + resourceLabels = common.DefaultResourceLabels(resourceName, asr.Instance.Name, AppSetControllerComponent) if err := asr.reconcileServiceAccount(); err != nil { asr.Logger.Info("reconciling applicationSet serviceaccount") @@ -46,15 +47,17 @@ func (asr *ApplicationSetReconciler) Reconcile() error { return err } - if asr.Instance.Spec.ApplicationSet.WebhookServer.Route.Enabled { - if err := asr.reconcileWebhookRoute(); err != nil { - asr.Logger.Info("reconciling applicationSet webhook route") - return err - } - } else { - if err := asr.deleteWebhookRoute(common.AppSetWebhookRouteName, asr.Instance.Namespace); err != nil { - asr.Logger.Error(err, "deleting applicationSet webhook route: failed to delete webhook route") - return err + if openshift.IsOpenShiftEnv() { + if asr.Instance.Spec.ApplicationSet.WebhookServer.Route.Enabled { + if err := asr.reconcileWebhookRoute(); err != nil { + asr.Logger.Info("reconciling applicationSet webhook route") + return err + } + } else { + if err := asr.deleteWebhookRoute(AppSetWebhookRouteName, asr.Instance.Namespace); err != nil { + asr.Logger.Error(err, "deleting applicationSet webhook route: failed to delete webhook route") + return err + } } } @@ -85,9 +88,11 @@ func (asr *ApplicationSetReconciler) DeleteResources() error { deletionError = err } - if err := asr.deleteWebhookRoute(resourceName, asr.Instance.Namespace); err != nil { - asr.Logger.Error(err, "DeleteResources: failed to delete webhook service") - deletionError = err + if openshift.IsOpenShiftEnv() { + if err := asr.deleteWebhookRoute(resourceName, asr.Instance.Namespace); err != nil { + asr.Logger.Error(err, "DeleteResources: failed to delete webhook service") + deletionError = err + } } if err := asr.deleteRoleBinding(resourceName, asr.Instance.Namespace); err != nil { diff --git a/controllers/argocd/applicationset/applicationset_test.go b/controllers/argocd/applicationset/applicationset_test.go index 954665060..a504e6084 100644 --- a/controllers/argocd/applicationset/applicationset_test.go +++ b/controllers/argocd/applicationset/applicationset_test.go @@ -15,7 +15,7 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" ) -var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.AppSetControllerComponent) +var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, AppSetControllerComponent) func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bool, objs ...runtime.Object) *ApplicationSetReconciler { s := scheme.Scheme @@ -24,7 +24,7 @@ func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bo assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(common.AppSetControllerComponent) + logger := ctrl.Log.WithName(AppSetControllerComponent) return &ApplicationSetReconciler{ Client: cl, diff --git a/controllers/argocd/applicationset/constants.go b/controllers/argocd/applicationset/constants.go new file mode 100644 index 000000000..29661ea06 --- /dev/null +++ b/controllers/argocd/applicationset/constants.go @@ -0,0 +1,14 @@ +package applicationset + +const ( + // Values + AppSetControllerComponent = "applicationset-controller" + AppSetController = "argocd-applicationset-controller" + AppSetGitlabSCMTlsCert = "appset-gitlab-scm-tls-cert" + AppSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" + AppSetWebhookRouteName = "applicationset-controller-webhook" + + // Commands + EntryPointSh = "entrypoint.sh" + ArgoCDRepoServer = "--argocd-repo-server" +) diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index f9e185193..073480aec 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -71,9 +71,6 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { }{ {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, func() { - if existingDeployment.Spec.Template.ObjectMeta.Labels == nil { - existingDeployment.Spec.Template.ObjectMeta.Labels = map[string]string{} - } existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, @@ -180,13 +177,13 @@ func (asr *ApplicationSetReconciler) getDeploymentRequest(dep appsv1.Deployment) return deploymentReq } -func (asr *ApplicationSetReconciler) getApplicationSetCommand() []string { +func (asr *ApplicationSetReconciler) getArgoApplicationSetCommand() []string { cmd := make([]string, 0) - cmd = append(cmd, common.EntryPointSh) - cmd = append(cmd, common.AppSetController) + cmd = append(cmd, EntryPointSh) + cmd = append(cmd, AppSetController) - cmd = append(cmd, common.ArgoCDRepoServer) + cmd = append(cmd, ArgoCDRepoServer) cmd = append(cmd, reposerver.GetRepoServerAddress(resourceName, asr.Instance.Namespace)) cmd = append(cmd, common.LogLevel) @@ -208,10 +205,10 @@ func (asr *ApplicationSetReconciler) getApplicationSetContainer(addSCMGitlabVolu appSetEnv := asr.Instance.Spec.ApplicationSet.Env appSetEnv = util.EnvMerge(appSetEnv, util.ProxyEnvVars(), false) container := &corev1.Container{ - Command: asr.getApplicationSetCommand(), + Command: asr.getArgoApplicationSetCommand(), Image: argocdcommon.GetArgoContainerImage(asr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: resourceName, + Name: AppSetController, Env: appSetEnv, Resources: asr.getApplicationSetResources(), SecurityContext: &corev1.SecurityContext{ @@ -260,8 +257,8 @@ func (asr *ApplicationSetReconciler) getApplicationSetContainer(addSCMGitlabVolu if addSCMGitlabVolumeMount { container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ - Name: common.AppSetGitlabSCMTlsCert, - MountPath: common.AppSetGitlabSCMTlsCertPath, + Name: AppSetGitlabSCMTlsCert, + MountPath: AppSetGitlabSCMTlsCertPath, }) } @@ -315,7 +312,7 @@ func (asr *ApplicationSetReconciler) getApplicationSetPodVolumes(addSCMGitlabVol } if addSCMGitlabVolumeMount { volumes = append(volumes, corev1.Volume{ - Name: common.AppSetGitlabSCMTlsCert, + Name: AppSetGitlabSCMTlsCert, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ diff --git a/controllers/argocd/applicationset/webhookroute.go b/controllers/argocd/applicationset/webhookroute.go index 338758425..8e41ca612 100644 --- a/controllers/argocd/applicationset/webhookroute.go +++ b/controllers/argocd/applicationset/webhookroute.go @@ -114,7 +114,7 @@ func (asr *ApplicationSetReconciler) getWebhookRouteSpec() routev1.RouteSpec { }, To: routev1.RouteTargetReference{ Kind: common.ServiceKind, - Name: argoutil.NameWithSuffix(asr.Instance.Name, common.AppSetControllerComponent), + Name: argoutil.NameWithSuffix(asr.Instance.Name, AppSetControllerComponent), }, } @@ -147,7 +147,7 @@ func (asr *ApplicationSetReconciler) getWebhookRouteRequest(route routev1.Route) func (asr *ApplicationSetReconciler) getDesiredWebhookRoute() *routev1.Route { desiredWebhook := &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ - Name: common.AppSetWebhookRouteName, + Name: AppSetWebhookRouteName, Namespace: asr.Instance.Namespace, Labels: resourceLabels, Annotations: asr.Instance.Annotations, diff --git a/controllers/argocd/applicationset/webhookroute_test.go b/controllers/argocd/applicationset/webhookroute_test.go index e55295705..846136a79 100644 --- a/controllers/argocd/applicationset/webhookroute_test.go +++ b/controllers/argocd/applicationset/webhookroute_test.go @@ -6,7 +6,6 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" routev1 "github.com/openshift/api/route/v1" @@ -59,7 +58,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { } updatedWebhookRoute := &routev1.Route{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: common.AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, updatedWebhookRoute) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, updatedWebhookRoute) if err != nil { t.Fatalf("Could not get updated WebhookRoute: %v", err) } @@ -99,7 +98,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabl } webhookRoute := &routev1.Route{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: common.AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, webhookRoute) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, webhookRoute) if err != nil { assert.Equal(t, errors.IsNotFound(err), true) } @@ -127,7 +126,7 @@ func TestApplicationSetReconciler_deleteWebhookRoute(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { asr := tt.setupClient(tt.webhookServerRouteEnabled) - if err := asr.deleteWebhookRoute(common.AppSetWebhookRouteName, ns.Name); (err != nil) != tt.wantErr { + if err := asr.deleteWebhookRoute(AppSetWebhookRouteName, ns.Name); (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") } else { diff --git a/pkg/networking/service.go b/pkg/networking/service.go index f1a1bc60d..d4b21df26 100644 --- a/pkg/networking/service.go +++ b/pkg/networking/service.go @@ -8,9 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" - "github.com/go-logr/logr" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -53,36 +51,6 @@ func RequestService(request ServiceRequest) (*corev1.Service, error) { return service, nil } -func EnsureAutoTLSAnnotation(svc *corev1.Service, secretName string, enabled bool, log logr.Logger) bool { - var autoTLSAnnotationName, autoTLSAnnotationValue string - - // We currently only support OpenShift for automatic TLS - if IsRouteAPIAvailable() { - autoTLSAnnotationName = common.ServiceBetaOpenshiftKeyCertSecret - if svc.Annotations == nil { - svc.Annotations = make(map[string]string) - } - autoTLSAnnotationValue = secretName - } - - if autoTLSAnnotationName != "" { - val, ok := svc.Annotations[autoTLSAnnotationName] - if enabled { - if !ok || val != secretName { - log.Info(fmt.Sprintf("requesting AutoTLS on service %s", svc.ObjectMeta.Name)) - svc.Annotations[autoTLSAnnotationName] = autoTLSAnnotationValue - return true - } - } else { - if ok { - log.Info(fmt.Sprintf("removing AutoTLS from service %s", svc.ObjectMeta.Name)) - delete(svc.Annotations, autoTLSAnnotationName) - return true - } - } - } - - return false // CreateService creates the specified Service using the provided client. func CreateService(service *corev1.Service, client cntrlClient.Client) error { return resource.CreateObject(service, client) diff --git a/pkg/workloads/deployment.go b/pkg/workloads/deployment.go index 4e5b87d9e..d4f1d2382 100644 --- a/pkg/workloads/deployment.go +++ b/pkg/workloads/deployment.go @@ -52,18 +52,6 @@ func RequestDeployment(request DeploymentRequest) (*appsv1.Deployment, error) { return deployment, nil } -// TriggerDeploymentRollout will update the label with the given key to trigger a new rollout of the Deployment. -func TriggerDeploymentRollout(client cntrlClient.Client, name, namespace string, updateChangedTime func(name, namespace string)) error { - currentDeployment, err := GetDeployment(name, namespace, client) - if err != nil { - if !errors.IsNotFound(err) { - return err - } - return nil - } - - updateChangedTime(currentDeployment.Name, currentDeployment.Namespace) - return UpdateDeployment(currentDeployment, client) // CreateDeployment creates the specified Deployment using the provided client. func CreateDeployment(deployment *appsv1.Deployment, client cntrlClient.Client) error { return resource.CreateObject(deployment, client) diff --git a/pkg/workloads/statefulset.go b/pkg/workloads/statefulset.go index f7d5e3e36..e1c389430 100644 --- a/pkg/workloads/statefulset.go +++ b/pkg/workloads/statefulset.go @@ -51,17 +51,6 @@ func RequestStatefulSet(request StatefulSetRequest) (*appsv1.StatefulSet, error) return StatefulSet, nil } -// TriggerStatefulSetRollout will update the label with the given key to trigger a new rollout of the StatefulSet. -func TriggerStatefulSetRollout(client cntrlClient.Client, name, namespace string, updateChangedTime func(name, namespace string)) error { - currentStatefulSet, err := GetStatefulSet(name, namespace, client) - if err != nil { - if !errors.IsNotFound(err) { - return err - } - return nil - } - updateChangedTime(currentStatefulSet.Name, currentStatefulSet.Namespace) - return UpdateStatefulSet(currentStatefulSet, client) // CreateStatefulSet creates the specified StatefulSet using the provided client. func CreateStatefulSet(statefulSet *appsv1.StatefulSet, client cntrlClient.Client) error { return resource.CreateObject(statefulSet, client) From e75bd95af02841caf3a141216816dbe9ea720f66 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 18 Jan 2024 07:31:38 -0500 Subject: [PATCH 56/94] remove notifs files Signed-off-by: Jaideep Rao --- controllers/argocd/notifications.go | 553 ----------------------- controllers/argocd/notifications_test.go | 449 ------------------ 2 files changed, 1002 deletions(-) delete mode 100644 controllers/argocd/notifications.go delete mode 100644 controllers/argocd/notifications_test.go diff --git a/controllers/argocd/notifications.go b/controllers/argocd/notifications.go deleted file mode 100644 index b7baa3ad0..000000000 --- a/controllers/argocd/notifications.go +++ /dev/null @@ -1,553 +0,0 @@ -package argocd - -import ( - "context" - "fmt" - "reflect" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argoutil" -) - -func (r *ReconcileArgoCD) reconcileNotificationsController(cr *argoproj.ArgoCD) error { - - log.Info("reconciling notifications serviceaccount") - sa, err := r.reconcileNotificationsServiceAccount(cr) - if err != nil { - return err - } - - log.Info("reconciling notifications role") - role, err := r.reconcileNotificationsRole(cr) - if err != nil { - return err - } - - log.Info("reconciling notifications role binding") - if err := r.reconcileNotificationsRoleBinding(cr, role, sa); err != nil { - return err - } - - log.Info("reconciling notifications configmap") - if err := r.reconcileNotificationsConfigMap(cr); err != nil { - return err - } - - log.Info("reconciling notifications secret") - if err := r.reconcileNotificationsSecret(cr); err != nil { - return err - } - - log.Info("reconciling notifications deployment") - if err := r.reconcileNotificationsDeployment(cr, sa); err != nil { - return err - } - - return nil -} - -// The code to create/delete notifications resources is written within the reconciliation logic itself. However, these functions must be called -// in the right order depending on whether resources are getting created or deleted. During creation we must create the role and sa first. -// RoleBinding and deployment are dependent on these resouces. During deletion the order is reversed. -// Deployment and RoleBinding must be deleted before the role and sa. deleteNotificationsResources will only be called during -// delete events, so we don't need to worry about duplicate, recurring reconciliation calls -func (r *ReconcileArgoCD) deleteNotificationsResources(cr *argoproj.ArgoCD) error { - - sa := &corev1.ServiceAccount{} - role := &rbacv1.Role{} - - if err := argoutil.FetchObject(r.Client, cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDNotificationsControllerComponent), sa); err != nil { - if !errors.IsNotFound(err) { - return err - } - } - if err := argoutil.FetchObject(r.Client, cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDNotificationsControllerComponent), role); err != nil { - if !errors.IsNotFound(err) { - return err - } - } - - log.Info("reconciling notifications deployment") - if err := r.reconcileNotificationsDeployment(cr, sa); err != nil { - return err - } - - log.Info("reconciling notifications secret") - if err := r.reconcileNotificationsSecret(cr); err != nil { - return err - } - - log.Info("reconciling notifications configmap") - if err := r.reconcileNotificationsConfigMap(cr); err != nil { - return err - } - - log.Info("reconciling notifications role binding") - if err := r.reconcileNotificationsRoleBinding(cr, role, sa); err != nil { - return err - } - - log.Info("reconciling notifications role") - _, err := r.reconcileNotificationsRole(cr) - if err != nil { - return err - } - - log.Info("reconciling notifications serviceaccount") - _, err = r.reconcileNotificationsServiceAccount(cr) - if err != nil { - return err - } - - return nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { - - sa := newServiceAccountWithName(common.ArgoCDNotificationsControllerComponent, cr) - - if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { - if !errors.IsNotFound(err) { - return nil, fmt.Errorf("failed to get the serviceAccount associated with %s : %s", sa.Name, err) - } - - // SA doesn't exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil, nil - } - - // SA doesn't exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, sa, r.Scheme); err != nil { - return nil, err - } - - log.Info(fmt.Sprintf("Creating serviceaccount %s", sa.Name)) - err := r.Client.Create(context.TODO(), sa) - if err != nil { - return nil, err - } - } - - // SA exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting serviceaccount %s as notifications is disabled", sa.Name)) - return nil, r.Client.Delete(context.TODO(), sa) - } - - return sa, nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsRole(cr *argoproj.ArgoCD) (*rbacv1.Role, error) { - - policyRules := policyRuleForNotificationsController() - desiredRole := newRole(common.ArgoCDNotificationsControllerComponent, policyRules, cr) - - existingRole := &rbacv1.Role{} - if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredRole.Name, existingRole); err != nil { - if !errors.IsNotFound(err) { - return nil, fmt.Errorf("failed to get the role associated with %s : %s", desiredRole.Name, err) - } - - // role does not exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil, nil - } - - // role does not exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredRole, r.Scheme); err != nil { - return nil, err - } - - log.Info(fmt.Sprintf("Creating role %s", desiredRole.Name)) - err := r.Client.Create(context.TODO(), desiredRole) - if err != nil { - return nil, err - } - return desiredRole, nil - } - - // role exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting role %s as notifications is disabled", existingRole.Name)) - return nil, r.Client.Delete(context.TODO(), existingRole) - } - - // role exists and should. Reconcile role if changed - if !reflect.DeepEqual(existingRole.Rules, desiredRole.Rules) { - existingRole.Rules = desiredRole.Rules - if err := controllerutil.SetControllerReference(cr, existingRole, r.Scheme); err != nil { - return nil, err - } - return existingRole, r.Client.Update(context.TODO(), existingRole) - } - - return desiredRole, nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoproj.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { - - desiredRoleBinding := newRoleBindingWithname(common.ArgoCDNotificationsControllerComponent, cr) - desiredRoleBinding.RoleRef = rbacv1.RoleRef{ - APIGroup: rbacv1.GroupName, - Kind: "Role", - Name: role.Name, - } - - desiredRoleBinding.Subjects = []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: sa.Name, - Namespace: sa.Namespace, - }, - } - - // fetch existing rolebinding by name - existingRoleBinding := &rbacv1.RoleBinding{} - if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: desiredRoleBinding.Name, Namespace: cr.Namespace}, existingRoleBinding); err != nil { - if !errors.IsNotFound(err) { - return fmt.Errorf("failed to get the rolebinding associated with %s : %s", desiredRoleBinding.Name, err) - } - - // roleBinding does not exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // roleBinding does not exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredRoleBinding, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating roleBinding %s", desiredRoleBinding.Name)) - return r.Client.Create(context.TODO(), desiredRoleBinding) - } - - // roleBinding exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting roleBinding %s as notifications is disabled", existingRoleBinding.Name)) - return r.Client.Delete(context.TODO(), existingRoleBinding) - } - - // roleBinding exists and should. Reconcile roleBinding if changed - if !reflect.DeepEqual(existingRoleBinding.RoleRef, desiredRoleBinding.RoleRef) { - // if the RoleRef changes, delete the existing role binding and create a new one - if err := r.Client.Delete(context.TODO(), existingRoleBinding); err != nil { - return err - } - } else if !reflect.DeepEqual(existingRoleBinding.Subjects, desiredRoleBinding.Subjects) { - existingRoleBinding.Subjects = desiredRoleBinding.Subjects - if err := controllerutil.SetControllerReference(cr, existingRoleBinding, r.Scheme); err != nil { - return err - } - return r.Client.Update(context.TODO(), existingRoleBinding) - } - - return nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { - - desiredDeployment := newDeploymentWithSuffix("notifications-controller", "controller", cr) - - desiredDeployment.Spec.Strategy = appsv1.DeploymentStrategy{ - Type: appsv1.RecreateDeploymentStrategyType, - } - - if replicas := getArgoCDNotificationsControllerReplicas(cr); replicas != nil { - desiredDeployment.Spec.Replicas = replicas - } - - notificationEnv := cr.Spec.Notifications.Env - // Let user specify their own environment first - notificationEnv = argoutil.EnvMerge(notificationEnv, proxyEnvVars(), false) - - podSpec := &desiredDeployment.Spec.Template.Spec - podSpec.SecurityContext = &corev1.PodSecurityContext{ - RunAsNonRoot: boolPtr(true), - } - AddSeccompProfileForOpenShift(r.Client, podSpec) - podSpec.ServiceAccountName = sa.ObjectMeta.Name - podSpec.Volumes = []corev1.Volume{ - { - Name: "tls-certs", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDTLSCertsConfigMapName, - }, - }, - }, - }, - { - Name: "argocd-repo-server-tls", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: common.ArgoCDRepoServerTLSSecretName, - Optional: boolPtr(true), - }, - }, - }, - } - - podSpec.Containers = []corev1.Container{{ - Command: getNotificationsCommand(cr), - Image: getArgoContainerImage(cr), - ImagePullPolicy: corev1.PullAlways, - Name: common.ArgoCDNotificationsControllerComponent, - Env: notificationEnv, - Resources: getNotificationsResources(cr), - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.IntOrString{ - IntVal: int32(9001), - }, - }, - }, - }, - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "tls-certs", - MountPath: "/app/config/tls", - }, - { - Name: "argocd-repo-server-tls", - MountPath: "/app/config/reposerver/tls", - }, - }, - WorkingDir: "/app", - }} - - // fetch existing deployment by name - deploymentChanged := false - existingDeployment := &appsv1.Deployment{} - if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: desiredDeployment.Name, Namespace: cr.Namespace}, existingDeployment); err != nil { - if !errors.IsNotFound(err) { - return fmt.Errorf("failed to get the deployment associated with %s : %s", existingDeployment.Name, err) - } - - // deployment does not exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // deployment does not exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredDeployment, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating deployment %s", desiredDeployment.Name)) - return r.Client.Create(context.TODO(), desiredDeployment) - } - - // deployment exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting deployment %s as notifications is disabled", existingDeployment.Name)) - return r.Client.Delete(context.TODO(), existingDeployment) - } - - // deployment exists and should. Reconcile deployment if changed - updateNodePlacement(existingDeployment, desiredDeployment, &deploymentChanged) - - if existingDeployment.Spec.Template.Spec.Containers[0].Image != desiredDeployment.Spec.Template.Spec.Containers[0].Image { - existingDeployment.Spec.Template.Spec.Containers[0].Image = desiredDeployment.Spec.Template.Spec.Containers[0].Image - existingDeployment.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Command, desiredDeployment.Spec.Template.Spec.Containers[0].Command) { - existingDeployment.Spec.Template.Spec.Containers[0].Command = desiredDeployment.Spec.Template.Spec.Containers[0].Command - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Env, - desiredDeployment.Spec.Template.Spec.Containers[0].Env) { - existingDeployment.Spec.Template.Spec.Containers[0].Env = desiredDeployment.Spec.Template.Spec.Containers[0].Env - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Volumes, desiredDeployment.Spec.Template.Spec.Volumes) { - existingDeployment.Spec.Template.Spec.Volumes = desiredDeployment.Spec.Template.Spec.Volumes - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Replicas, desiredDeployment.Spec.Replicas) { - existingDeployment.Spec.Replicas = desiredDeployment.Spec.Replicas - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts) { - existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts = desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Resources, desiredDeployment.Spec.Template.Spec.Containers[0].Resources) { - existingDeployment.Spec.Template.Spec.Containers[0].Resources = desiredDeployment.Spec.Template.Spec.Containers[0].Resources - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.ServiceAccountName, desiredDeployment.Spec.Template.Spec.ServiceAccountName) { - existingDeployment.Spec.Template.Spec.ServiceAccountName = desiredDeployment.Spec.Template.Spec.ServiceAccountName - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Labels, desiredDeployment.Labels) { - existingDeployment.Labels = desiredDeployment.Labels - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Labels, desiredDeployment.Spec.Template.Labels) { - existingDeployment.Spec.Template.Labels = desiredDeployment.Spec.Template.Labels - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Selector, desiredDeployment.Spec.Selector) { - existingDeployment.Spec.Selector = desiredDeployment.Spec.Selector - deploymentChanged = true - } - - if deploymentChanged { - return r.Client.Update(context.TODO(), existingDeployment) - } - - return nil - -} - -// reconcileNotificationsConfigMap only creates/deletes the argocd-notifications-cm based on whether notifications is enabled/disabled in the CR -// It does not reconcile/overwrite any fields or information in the configmap itself -func (r *ReconcileArgoCD) reconcileNotificationsConfigMap(cr *argoproj.ArgoCD) error { - - desiredConfigMap := newConfigMapWithName("argocd-notifications-cm", cr) - desiredConfigMap.Data = getDefaultNotificationsConfig() - - cmExists := true - existingConfigMap := &corev1.ConfigMap{} - if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredConfigMap.Name, existingConfigMap); err != nil { - if !errors.IsNotFound(err) { - return fmt.Errorf("failed to get the configmap associated with %s : %s", desiredConfigMap.Name, err) - } - cmExists = false - } - - if cmExists { - // CM exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting configmap %s as notifications is disabled", existingConfigMap.Name)) - return r.Client.Delete(context.TODO(), existingConfigMap) - } - - // CM exists and should, nothing to do here - return nil - } - - // CM doesn't exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // CM doesn't exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredConfigMap, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating configmap %s", desiredConfigMap.Name)) - err := r.Client.Create(context.TODO(), desiredConfigMap) - if err != nil { - return err - } - - return nil -} - -// reconcileNotificationsSecret only creates/deletes the argocd-notifications-secret based on whether notifications is enabled/disabled in the CR -// It does not reconcile/overwrite any fields or information in the secret itself -func (r *ReconcileArgoCD) reconcileNotificationsSecret(cr *argoproj.ArgoCD) error { - - desiredSecret := argoutil.NewSecretWithName(cr, "argocd-notifications-secret") - - secretExists := true - existingSecret := &corev1.Secret{} - if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredSecret.Name, existingSecret); err != nil { - if !errors.IsNotFound(err) { - return fmt.Errorf("failed to get the secret associated with %s : %s", desiredSecret.Name, err) - } - secretExists = false - } - - if secretExists { - // secret exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting secret %s as notifications is disabled", existingSecret.Name)) - return r.Client.Delete(context.TODO(), existingSecret) - } - - // secret exists and should, nothing to do here - return nil - } - - // secret doesn't exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // secret doesn't exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredSecret, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating secret %s", desiredSecret.Name)) - err := r.Client.Create(context.TODO(), desiredSecret) - if err != nil { - return err - } - - return nil -} - -func getNotificationsCommand(cr *argoproj.ArgoCD) []string { - - cmd := make([]string, 0) - cmd = append(cmd, "argocd-notifications") - - cmd = append(cmd, "--loglevel") - cmd = append(cmd, getLogLevel(cr.Spec.Notifications.LogLevel)) - - if cr.Spec.Repo.IsEnabled() { - cmd = append(cmd, "--argocd-repo-server", getRepoServerAddress(cr)) - } else { - log.Info("Repo Server is disabled. This would affect the functioning of Notification Controller.") - } - - return cmd -} - -// getNotificationsResources will return the ResourceRequirements for the Notifications container. -func getNotificationsResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { - resources := corev1.ResourceRequirements{} - - // Allow override of resource requirements from CR - if cr.Spec.Notifications.Resources != nil { - resources = *cr.Spec.Notifications.Resources - } - - return resources -} diff --git a/controllers/argocd/notifications_test.go b/controllers/argocd/notifications_test.go deleted file mode 100644 index 6418f6fc0..000000000 --- a/controllers/argocd/notifications_test.go +++ /dev/null @@ -1,449 +0,0 @@ -package argocd - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argoutil" -) - -func TestReconcileNotifications_CreateRoles(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - _, err := r.reconcileNotificationsRole(a) - assert.NoError(t, err) - - testRole := &rbacv1.Role{} - assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, testRole)) - - desiredPolicyRules := policyRuleForNotificationsController() - - assert.Equal(t, desiredPolicyRules, testRole.Rules) - - a.Spec.Notifications.Enabled = false - _, err = r.reconcileNotificationsRole(a) - assert.NoError(t, err) - - err = r.Client.Get(context.TODO(), types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, testRole) - assert.True(t, errors.IsNotFound(err)) -} - -func TestReconcileNotifications_CreateServiceAccount(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - desiredSa, err := r.reconcileNotificationsServiceAccount(a) - assert.NoError(t, err) - - testSa := &corev1.ServiceAccount{} - assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, testSa)) - - assert.Equal(t, testSa.Name, desiredSa.Name) - - a.Spec.Notifications.Enabled = false - _, err = r.reconcileNotificationsServiceAccount(a) - assert.NoError(t, err) - - err = r.Client.Get(context.TODO(), types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, testSa) - assert.True(t, errors.IsNotFound(err)) - -} - -func TestReconcileNotifications_CreateRoleBinding(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - role := &rbacv1.Role{ObjectMeta: metav1.ObjectMeta{Name: "role-name"}} - sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "sa-name"}} - - err := r.reconcileNotificationsRoleBinding(a, role, sa) - assert.NoError(t, err) - - roleBinding := &rbacv1.RoleBinding{} - assert.NoError(t, r.Client.Get( - context.TODO(), - types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, - roleBinding)) - - assert.Equal(t, roleBinding.RoleRef.Name, role.Name) - assert.Equal(t, roleBinding.Subjects[0].Name, sa.Name) - - a.Spec.Notifications.Enabled = false - err = r.reconcileNotificationsRoleBinding(a, role, sa) - assert.NoError(t, err) - - err = r.Client.Get(context.TODO(), types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, roleBinding) - assert.True(t, errors.IsNotFound(err)) -} - -func TestReconcileNotifications_CreateDeployments(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - sa := corev1.ServiceAccount{} - - assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) - - deployment := &appsv1.Deployment{} - assert.NoError(t, r.Client.Get( - context.TODO(), - types.NamespacedName{ - Name: a.Name + "-notifications-controller", - Namespace: a.Namespace, - }, - deployment)) - - // Ensure the created Deployment has the expected properties - assert.Equal(t, deployment.Spec.Template.Spec.ServiceAccountName, sa.ObjectMeta.Name) - - want := []corev1.Container{{ - Command: []string{"argocd-notifications", "--loglevel", "info", "--argocd-repo-server", "argocd-repo-server.argocd.svc.cluster.local:8081"}, - Image: argoutil.CombineImageTag(common.ArgoCDDefaultArgoImage, common.ArgoCDDefaultArgoVersion), - ImagePullPolicy: corev1.PullAlways, - Name: "argocd-notifications-controller", - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "tls-certs", - MountPath: "/app/config/tls", - }, - { - Name: "argocd-repo-server-tls", - MountPath: "/app/config/reposerver/tls", - }, - }, - Resources: corev1.ResourceRequirements{}, - WorkingDir: "/app", - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.IntOrString{ - IntVal: int32(9001), - }, - }, - }, - }, - }} - - if diff := cmp.Diff(want, deployment.Spec.Template.Spec.Containers); diff != "" { - t.Fatalf("failed to reconcile notifications-controller deployment containers:\n%s", diff) - } - - volumes := []corev1.Volume{ - { - Name: "tls-certs", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "argocd-tls-certs-cm", - }, - }, - }, - }, - { - Name: "argocd-repo-server-tls", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: "argocd-repo-server-tls", - Optional: boolPtr(true), - }, - }, - }, - } - - if diff := cmp.Diff(volumes, deployment.Spec.Template.Spec.Volumes); diff != "" { - t.Fatalf("failed to reconcile notifications-controller deployment volumes:\n%s", diff) - } - - expectedSelector := &metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.ArgoCDKeyName: deployment.Name, - }, - } - - if diff := cmp.Diff(expectedSelector, deployment.Spec.Selector); diff != "" { - t.Fatalf("failed to reconcile notifications-controller label selector:\n%s", diff) - } - - a.Spec.Notifications.Enabled = false - err := r.reconcileNotificationsDeployment(a, &sa) - assert.NoError(t, err) - - err = r.Client.Get(context.TODO(), types.NamespacedName{ - Name: generateResourceName(common.ArgoCDNotificationsControllerComponent, a), - Namespace: a.Namespace, - }, deployment) - assert.True(t, errors.IsNotFound(err)) -} - -func TestReconcileNotifications_CreateSecret(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - err := r.reconcileNotificationsSecret(a) - assert.NoError(t, err) - - testSecret := &corev1.Secret{} - assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{ - Name: "argocd-notifications-secret", - Namespace: a.Namespace, - }, testSecret)) - - a.Spec.Notifications.Enabled = false - err = r.reconcileNotificationsSecret(a) - assert.NoError(t, err) - secret := &corev1.Secret{} - err = r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-notifications-secret", Namespace: a.Namespace}, secret) - assertNotFound(t, err) -} - -func TestReconcileNotifications_CreateConfigMap(t *testing.T) { - logf.SetLogger(ZapLogger(true)) - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - err := r.reconcileNotificationsConfigMap(a) - assert.NoError(t, err) - - testCm := &corev1.ConfigMap{} - assert.NoError(t, r.Client.Get(context.TODO(), types.NamespacedName{ - Name: "argocd-notifications-cm", - Namespace: a.Namespace, - }, testCm)) - - assert.True(t, len(testCm.Data) > 0) - - a.Spec.Notifications.Enabled = false - err = r.reconcileNotificationsConfigMap(a) - assert.NoError(t, err) - testCm = &corev1.ConfigMap{} - err = r.Client.Get(context.TODO(), types.NamespacedName{Name: "argocd-notifications-cm", Namespace: a.Namespace}, testCm) - assertNotFound(t, err) -} - -func TestReconcileNotifications_testEnvVars(t *testing.T) { - - envMap := []corev1.EnvVar{ - { - Name: "foo", - Value: "bar", - }, - } - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - a.Spec.Notifications.Env = envMap - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - sa := corev1.ServiceAccount{} - assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) - - deployment := &appsv1.Deployment{} - assert.NoError(t, r.Client.Get( - context.TODO(), - types.NamespacedName{ - Name: a.Name + "-notifications-controller", - Namespace: a.Namespace, - }, - deployment)) - - if diff := cmp.Diff(envMap, deployment.Spec.Template.Spec.Containers[0].Env); diff != "" { - t.Fatalf("failed to reconcile notifications-controller deployment env:\n%s", diff) - } - - // Verify any manual updates to the env vars should be overridden by the operator. - unwantedEnv := []corev1.EnvVar{ - { - Name: "foo", - Value: "bar", - }, - { - Name: "ping", - Value: "pong", - }, - } - - deployment.Spec.Template.Spec.Containers[0].Env = unwantedEnv - assert.NoError(t, r.Client.Update(context.TODO(), deployment)) - - // Reconcile back - assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) - - // Get the updated deployment - assert.NoError(t, r.Client.Get( - context.TODO(), - types.NamespacedName{ - Name: a.Name + "-notifications-controller", - Namespace: a.Namespace, - }, - deployment)) - - if diff := cmp.Diff(envMap, deployment.Spec.Template.Spec.Containers[0].Env); diff != "" { - t.Fatalf("operator failed to override the manual changes to notification controller:\n%s", diff) - } -} - -func TestReconcileNotifications_testLogLevel(t *testing.T) { - - testLogLevel := "debug" - a := makeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Notifications.Enabled = true - a.Spec.Notifications.LogLevel = testLogLevel - }) - - resObjs := []client.Object{a} - subresObjs := []client.Object{a} - runtimeObjs := []runtime.Object{} - sch := makeTestReconcilerScheme(argoproj.AddToScheme) - cl := makeTestReconcilerClient(sch, resObjs, subresObjs, runtimeObjs) - r := makeTestReconciler(cl, sch) - - sa := corev1.ServiceAccount{} - assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) - - deployment := &appsv1.Deployment{} - assert.NoError(t, r.Client.Get( - context.TODO(), - types.NamespacedName{ - Name: a.Name + "-notifications-controller", - Namespace: a.Namespace, - }, - deployment)) - - expectedCMD := []string{ - "argocd-notifications", - "--loglevel", - "debug", - "--argocd-repo-server", - "argocd-repo-server.argocd.svc.cluster.local:8081", - } - - if diff := cmp.Diff(expectedCMD, deployment.Spec.Template.Spec.Containers[0].Command); diff != "" { - t.Fatalf("failed to reconcile notifications-controller deployment logLevel:\n%s", diff) - } - - // Verify any manual updates to the logLevel should be overridden by the operator. - unwantedCommand := []string{ - "argocd-notifications", - "--logLevel", - "info", - } - - deployment.Spec.Template.Spec.Containers[0].Command = unwantedCommand - assert.NoError(t, r.Client.Update(context.TODO(), deployment)) - - // Reconcile back - assert.NoError(t, r.reconcileNotificationsDeployment(a, &sa)) - - // Get the updated deployment - assert.NoError(t, r.Client.Get( - context.TODO(), - types.NamespacedName{ - Name: a.Name + "-notifications-controller", - Namespace: a.Namespace, - }, - deployment)) - - if diff := cmp.Diff(expectedCMD, deployment.Spec.Template.Spec.Containers[0].Command); diff != "" { - t.Fatalf("operator failed to override the manual changes to notification controller:\n%s", diff) - } -} From ba5a79f2d7faecdf5d505d1eedc4de7d44b6592e Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 18 Jan 2024 07:51:10 -0500 Subject: [PATCH 57/94] minimize changes outside of reposerver folder Signed-off-by: Jaideep Rao --- common/TOBEREMOVED.go | 43 ++++ common/envVars.go | 12 - common/keys.go | 5 + common/redis.go | 83 +++++-- common/reposerver.go | 2 + common/values.go | 9 + .../argocd/appcontroller/appcontroller.go | 2 +- controllers/argocd/argocdcommon/argohelper.go | 136 ----------- controllers/argocd/argocdcommon/helper.go | 12 +- controllers/argocd/argocdcommon/image.go | 43 ++++ controllers/argocd/argocdcommon/secret.go | 99 ++++++++ controllers/argocd/argocdcommon/testing.go | 1 - controllers/argocd/argocdcommon/workloads.go | 29 +++ controllers/argocd/notifications/configmap.go | 1 + .../argocd/notifications/deployment.go | 5 +- .../notifications/notifications_test.go | 4 +- controllers/argocd/notifications/role.go | 1 + controllers/argocd/notifications/secret.go | 1 + pkg/argoutil/TOBEREMOVED.go | 109 --------- pkg/argoutil/resource.go | 20 +- pkg/argoutil/tls.go | 136 +++++++++++ pkg/cluster/event.go | 8 +- pkg/cluster/namespace.go | 10 +- pkg/cluster/namespace_test.go | 4 +- pkg/monitoring/monitoring_test.go | 4 +- pkg/monitoring/prometheusRule.go | 11 +- pkg/monitoring/serviceMonitor.go | 10 +- pkg/mutation/mutation.go | 6 +- pkg/networking/ingress.go | 10 +- pkg/networking/networking_test.go | 4 +- pkg/networking/service.go | 11 +- pkg/openshift/mutation.go | 142 +++++++++++- pkg/openshift/networking.go | 10 +- pkg/openshift/openshift_test.go | 4 +- pkg/openshift/workloads.go | 10 +- pkg/permissions/clusterrole.go | 8 +- pkg/permissions/permissions_test.go | 4 +- pkg/permissions/role.go | 10 +- pkg/resource/clusterScoped.go | 22 +- pkg/resource/namespaceScoped.go | 22 +- pkg/util/error.go | 63 ++++++ pkg/util/error_test.go | 214 ++++++++++++++++++ pkg/util/image.go | 4 + pkg/util/image_test.go | 53 +++++ pkg/util/int.go | 5 + pkg/util/interface.go | 36 +++ pkg/util/interface_test.go | 142 ++++++++++++ pkg/util/log.go | 22 ++ pkg/util/log_test.go | 56 +++++ pkg/util/map_test.go | 93 ++++++++ pkg/util/string.go | 19 +- pkg/util/string_test.go | 141 ++++++++++++ pkg/util/time_test.go | 31 +++ pkg/workloads/configmap.go | 10 +- pkg/workloads/deployment.go | 10 +- pkg/workloads/hpa.go | 10 +- pkg/workloads/secret.go | 10 +- pkg/workloads/statefulset.go | 11 +- pkg/workloads/workloads_test.go | 4 +- 59 files changed, 1613 insertions(+), 384 deletions(-) delete mode 100644 controllers/argocd/argocdcommon/argohelper.go create mode 100644 controllers/argocd/argocdcommon/image.go create mode 100644 controllers/argocd/argocdcommon/secret.go create mode 100644 controllers/argocd/argocdcommon/workloads.go create mode 100644 pkg/argoutil/tls.go create mode 100644 pkg/util/error.go create mode 100644 pkg/util/error_test.go create mode 100644 pkg/util/image_test.go create mode 100644 pkg/util/interface.go create mode 100644 pkg/util/interface_test.go create mode 100644 pkg/util/log.go create mode 100644 pkg/util/log_test.go create mode 100644 pkg/util/map_test.go create mode 100644 pkg/util/string_test.go create mode 100644 pkg/util/time_test.go diff --git a/common/TOBEREMOVED.go b/common/TOBEREMOVED.go index 9b90d3c1f..c6ce3ab01 100644 --- a/common/TOBEREMOVED.go +++ b/common/TOBEREMOVED.go @@ -117,6 +117,49 @@ const ( // ArgoCDNotificationsControllerComponent is the name of the Notifications controller control plane component ArgoCDNotificationsControllerComponent = "argocd-notifications-controller" + + ArgoCDDefaultRedisSuffix = "redis" + + // ArgoCDRedisComponent is the name of the Redis control plane component + ArgoCDRedisComponent = "argocd-redis" + + // ArgoCDRedisHAComponent is the name of the Redis HA control plane component + ArgoCDRedisHAComponent = "argocd-redis-ha" + + // ArgoCDDefaultRedisPort is the default listen port for Redis. + ArgoCDDefaultRedisPort = 6379 + + // ArgoCDDefaultRedisImage is the Redis container image to use when not specified. + ArgoCDDefaultRedisImage = "redis" + + // ArgoCDDefaultRedisSentinelPort is the default listen port for Redis sentinel. + ArgoCDDefaultRedisSentinelPort = 26379 + + // ArgoCDDefaultRedisVersion is the Redis container image tag to use when not specified. + ArgoCDDefaultRedisVersion = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + + // ArgoCDDefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. + ArgoCDDefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + + // ArgoCDDefaultRedisConfigPath is the default Redis configuration directory when not specified. + ArgoCDDefaultRedisConfigPath = "/var/lib/redis" + + // ArgoCDDefaultRedisHAReplicas is the defaul number of replicas for Redis when rinning in HA mode. + ArgoCDDefaultRedisHAReplicas = int32(3) + + // ArgoCDDefaultRedisHAProxyImage is the default Redis HAProxy image to use when not specified. + ArgoCDDefaultRedisHAProxyImage = "haproxy" + + // ArgoCDDefaultRedisHAProxyVersion is the default Redis HAProxy image tag to use when not specified. + ArgoCDDefaultRedisHAProxyVersion = "sha256:7392fbbbb53e9e063ca94891da6656e6062f9d021c0e514888a91535b9f73231" // 2.0.25-alpine + + // ArgoCDRedisHAProxyImageEnvVar is the environment variable used to get the image + // to used for the Redis HA Proxy container. + ArgoCDRedisHAProxyImageEnvVar = "ARGOCD_REDIS_HA_PROXY_IMAGE" + + // ArgoCDRedisHAImageEnvVar is the environment variable used to get the image + // to used for the the Redis container in HA mode. + ArgoCDRedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" ) // DefaultLabels returns the default set of labels for controllers. diff --git a/common/envVars.go b/common/envVars.go index f7e705382..9b8593f28 100644 --- a/common/envVars.go +++ b/common/envVars.go @@ -18,18 +18,6 @@ const ( // to used for the Dex container. ArgoCDRepoImageEnvVar = "ARGOCD_REPOSERVER_IMAGE" - // ArgoCDRedisHAProxyImageEnvVar is the environment variable used to get the image - // to used for the Redis HA Proxy container. - ArgoCDRedisHAProxyImageEnvVar = "ARGOCD_REDIS_HA_PROXY_IMAGE" - - // ArgoCDRedisHAImageEnvVar is the environment variable used to get the image - // to used for the the Redis container in HA mode. - ArgoCDRedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" - - // ArgoCDRedisImageEnvVar is the environment variable used to get the image - // to used for the Redis container. - ArgoCDRedisImageEnvVar = "ARGOCD_REDIS_IMAGE" - // ArgoCDGrafanaImageEnvVar is the environment variable used to get the image // to used for the Grafana container. ArgoCDGrafanaImageEnvVar = "ARGOCD_GRAFANA_IMAGE" diff --git a/common/keys.go b/common/keys.go index 956ece08d..2998bdc37 100644 --- a/common/keys.go +++ b/common/keys.go @@ -208,3 +208,8 @@ const ( // ArgoCDArgoprojKeyManagedByClusterArgoCD is needed to identify namespace mentioned as sourceNamespace on ArgoCD ArgoCDArgoprojKeyManagedByClusterArgoCD = "argocd.argoproj.io/managed-by-cluster-argocd" ) + +// misc +const ( + TLSSecretNameKey = "tls-secret-name" +) diff --git a/common/redis.go b/common/redis.go index 97302fe2c..b687da112 100644 --- a/common/redis.go +++ b/common/redis.go @@ -2,14 +2,12 @@ package common // names const ( - // ArgoCDRedisComponent is the name of the Redis control plane component - ArgoCDRedisComponent = "argocd-redis" + RedisController = "redis-controller" - // ArgoCDRedisHAComponent is the name of the Redis HA control plane component - ArgoCDRedisHAComponent = "argocd-redis-ha" + // RedisComponentName is the Redis control plane component + RedisComponent = "redis" - //ArgoCDDefaultRedisSuffix is the default suffix to use for Redis resources. - ArgoCDDefaultRedisSuffix = "redis" + HAProxyName = "haproxy" // ArgoCDRedisHAConfigMapName is the upstream ArgoCD Redis HA ConfigMap name. ArgoCDRedisHAConfigMapName = "argocd-redis-ha-configmap" @@ -24,33 +22,70 @@ const ( ArgoCDRedisServerTLSSecretName = "argocd-operator-redis-tls" ) -// deafults +// suffixes const ( + //RedisSuffix is the default suffix to use for Redis resources. + RedisSuffix = "redis" - // ArgoCDDefaultRedisConfigPath is the default Redis configuration directory when not specified. - ArgoCDDefaultRedisConfigPath = "/var/lib/redis" + RedisHASuffix = "redis-ha" - // ArgoCDDefaultRedisHAReplicas is the defaul number of replicas for Redis when rinning in HA mode. - ArgoCDDefaultRedisHAReplicas = int32(3) + RedisHAProxySuffix = "redis-ha-haproxy" - // ArgoCDDefaultRedisHAProxyImage is the default Redis HAProxy image to use when not specified. - ArgoCDDefaultRedisHAProxyImage = "haproxy" + RedisHAServerSuffix = "redis-ha-server" - // ArgoCDDefaultRedisHAProxyVersion is the default Redis HAProxy image tag to use when not specified. - ArgoCDDefaultRedisHAProxyVersion = "sha256:7392fbbbb53e9e063ca94891da6656e6062f9d021c0e514888a91535b9f73231" // 2.0.25-alpine + RedisHAAnnouceSuffix = "redis-ha-announce" +) + +// defaults +const ( + + // DefaultRedisConfigPath is the default Redis configuration directory when not specified. + DefaultRedisConfigPath = "/var/lib/redis" + + // DefaultRedisHAReplicas is the defaul number of replicas for Redis when rinning in HA mode. + DefaultRedisHAReplicas = int32(3) + + // DefaultRedisHAProxyImage is the default Redis HAProxy image to use when not specified. + DefaultRedisHAProxyImage = "haproxy" + + // DefaultRedisHAProxyVersion is the default Redis HAProxy image tag to use when not specified. + DefaultRedisHAProxyVersion = "sha256:7392fbbbb53e9e063ca94891da6656e6062f9d021c0e514888a91535b9f73231" // 2.0.25-alpine // ArgoCDDefaultRedisImage is the Redis container image to use when not specified. - ArgoCDDefaultRedisImage = "redis" + DefaultRedisImage = "redis" + + // DefaultRedisPort is the default listen port for Redis. + DefaultRedisPort = 6379 - // ArgoCDDefaultRedisPort is the default listen port for Redis. - ArgoCDDefaultRedisPort = 6379 + // DefaultRedisSentinelPort is the default listen port for Redis sentinel. + DefaultRedisSentinelPort = 26379 - // ArgoCDDefaultRedisSentinelPort is the default listen port for Redis sentinel. - ArgoCDDefaultRedisSentinelPort = 26379 + // DefaultRedisVersion is the Redis container image tag to use when not specified. + DefaultRedisVersion = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine - // ArgoCDDefaultRedisVersion is the Redis container image tag to use when not specified. - ArgoCDDefaultRedisVersion = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + // DefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. + DefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine +) + +// env vars +const ( + // RedisHAProxyImageEnvVar is the environment variable used to get the image + // to used for the Redis HA Proxy container. + RedisHAProxyImageEnvVar = "ARGOCD_REDIS_HA_PROXY_IMAGE" + + // RedisHAImageEnvVar is the environment variable used to get the image + // to used for the the Redis container in HA mode. + RedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" - // ArgoCDDefaultRedisVersionHA is the Redis container image tag to use when not specified in HA mode. - ArgoCDDefaultRedisVersionHA = "sha256:8061ca607db2a0c80010aeb5fc9bed0253448bc68711eaa14253a392f6c48280" // 6.2.4-alpine + // RedisImageEnvVar is the environment variable used to get the image + // to used for the Redis container. + RedisImageEnvVar = "ARGOCD_REDIS_IMAGE" + + // RedisConfigPathEnvVar is the environment variiable used to get the redis configuration templates + RedisConfigPathEnvVar = "REDIS_CONFIG_PATH" +) + +// keys +const ( + RedisTLSCertChangedKey = "redis.tls.cert.changed" ) diff --git a/common/reposerver.go b/common/reposerver.go index 51a190700..17575b899 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -4,6 +4,8 @@ package common const ( // ArgoCDRepoServerTLSSecretName is the name of the TLS secret for the repo-server ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" + + RepoServerSuffix = "-repo-server" ) // values diff --git a/common/values.go b/common/values.go index 0747801be..5e3b002be 100644 --- a/common/values.go +++ b/common/values.go @@ -41,6 +41,14 @@ const ( // ArgoCDMetrics is the resource metrics key for labels. ArgoCDMetrics = "metrics" + + ArgoCDStatusUnknown = "Unknown" + + ArgoCDStatusPending = "Pending" + + ArgoCDStatusRunning = "Running" + + ArgoCDStatusAvailable = "Available" ) // general values @@ -75,6 +83,7 @@ const ( SecretKind = "Secret" ServiceKind = "Service" ServiceAccountKind = "ServiceAccount" + ArgoCDKind = "ArgoCD" ) // Commnds diff --git a/controllers/argocd/appcontroller/appcontroller.go b/controllers/argocd/appcontroller/appcontroller.go index ccbd27ce9..3dac91850 100644 --- a/controllers/argocd/appcontroller/appcontroller.go +++ b/controllers/argocd/appcontroller/appcontroller.go @@ -9,7 +9,7 @@ import ( ) type AppControllerReconciler struct { - Client client.Client + Client *client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD ClusterScoped bool diff --git a/controllers/argocd/argocdcommon/argohelper.go b/controllers/argocd/argocdcommon/argohelper.go deleted file mode 100644 index a924622ee..000000000 --- a/controllers/argocd/argocdcommon/argohelper.go +++ /dev/null @@ -1,136 +0,0 @@ -package argocdcommon - -import ( - "context" - "fmt" - "os" - "strings" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/util" - "github.com/argoproj-labs/argocd-operator/pkg/workloads" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" -) - -func GetArgoContainerImage(cr *argoproj.ArgoCD) string { - defaultTag, defaultImg := false, false - img := cr.Spec.Image - if img == "" { - img = common.ArgoCDDefaultArgoImage - defaultImg = true - } - - tag := cr.Spec.Version - if tag == "" { - tag = common.ArgoCDDefaultArgoVersion - defaultTag = true - } - if e := os.Getenv(common.ArgoCDImageEnvVar); e != "" && (defaultTag && defaultImg) { - return e - } - - return util.CombineImageTag(img, tag) -} - -// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container -func GetArgoCmpServerInitCommand() []string { - cmd := make([]string, 0) - cmd = append(cmd, "cp") - cmd = append(cmd, "-n") - cmd = append(cmd, "/usr/local/bin/argocd") - cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") - return cmd -} - -// isOwnerOfInterest returns true if the given owner is one of the Argo CD services that -// may have been made the owner of the tls secret created by the OpenShift service CA, used -// to secure communication amongst the Argo CD components. -func IsOwnerOfInterest(owner metav1.OwnerReference) bool { - if owner.Kind != "Service" { - return false - } - if strings.HasSuffix(owner.Name, "-repo-server") { - return true - } - if strings.HasSuffix(owner.Name, "-redis") { - return true - } - return false -} - -// TriggerRollout will trigger a rollout of a Kubernetes resource specified as -// obj. It currently supports Deployment and StatefulSet resources. -func TriggerRollout(client cntrlClient.Client, name, namespace, resType string, opt func(name string, namespace string)) error { - switch resType { - case common.DeploymentKind: - return workloads.TriggerDeploymentRollout(client, name, namespace, opt) - case common.StatefulSetKind: - return workloads.TriggerStatefulSetRollout(client, name, namespace, opt) - default: - return fmt.Errorf("resource of unknown type %T, cannot trigger rollout", resType) - } -} - -func ShouldUseTLS(client cntrlClient.Client, instanceNamespace string) (bool, error) { - tlsSecretName := types.NamespacedName{Namespace: instanceNamespace, Name: common.ArgoCDRedisServerTLSSecretName} - var tlsSecretObj corev1.Secret - if err := client.Get(context.TODO(), tlsSecretName, &tlsSecretObj); err != nil { - if !errors.IsNotFound(err) { - return false, err - } - return false, nil - } - - secretOwnerRefs := tlsSecretObj.GetOwnerReferences() - if len(secretOwnerRefs) > 0 { - // OpenShift service CA makes the owner reference for the TLS secret to the - // service, which in turn is owned by the controller. This method performs - // a lookup of the controller through the intermediate owning service. - for _, secretOwner := range secretOwnerRefs { - if IsOwnerOfInterest(secretOwner) { - key := cntrlClient.ObjectKey{Name: secretOwner.Name, Namespace: tlsSecretObj.GetNamespace()} - svc := &corev1.Service{} - // Get the owning object of the secret - if err := client.Get(context.TODO(), key, svc); err != nil { - return false, err - } - - // If there's an object of kind ArgoCD in the owner's list, - // this will be our reconciled object. - serviceOwnerRefs := svc.GetOwnerReferences() - for _, serviceOwner := range serviceOwnerRefs { - if serviceOwner.Kind == "ArgoCD" { - return true, nil - } - } - } - } - } else { - // For secrets without owner (i.e. manually created), we apply some - // heuristics. This may not be as accurate (e.g. if the user made a - // typo in the resource's name), but should be good enough for now. - if _, ok := tlsSecretObj.Annotations[common.ArgoCDArgoprojKeyName]; ok { - return true, nil - } - } - return false, nil -} - -// getRedisServerAddress will return the Redis service address for the given ArgoCD. -func GetRedisServerAddress(cr *argoproj.ArgoCD) string { - if cr.Spec.HA.Enabled { - return GetRedisHAProxyAddress(cr.Namespace) - } - return argoutil.FqdnServiceRef(common.ArgoCDDefaultRedisSuffix, cr.Namespace, common.ArgoCDDefaultRedisPort) -} - -// getRedisHAProxyAddress will return the Redis HA Proxy service address for the given ArgoCD. -func GetRedisHAProxyAddress(namespace string) string { - return argoutil.FqdnServiceRef(common.RedisHAProxyServiceName, namespace, common.ArgoCDDefaultRedisPort) -} diff --git a/controllers/argocd/argocdcommon/helper.go b/controllers/argocd/argocdcommon/helper.go index 0481ef655..3eaf1d514 100644 --- a/controllers/argocd/argocdcommon/helper.go +++ b/controllers/argocd/argocdcommon/helper.go @@ -8,12 +8,14 @@ import ( ) func UpdateIfChanged(existingVal, desiredVal interface{}, extraAction func(), changed *bool) { - if !reflect.DeepEqual(existingVal, desiredVal) { - reflect.ValueOf(existingVal).Elem().Set(reflect.ValueOf(desiredVal).Elem()) - if extraAction != nil { - extraAction() + if util.IsPtr(existingVal) && util.IsPtr(desiredVal) { + if !reflect.DeepEqual(existingVal, desiredVal) { + reflect.ValueOf(existingVal).Elem().Set(reflect.ValueOf(desiredVal).Elem()) + if extraAction != nil { + extraAction() + } + *changed = true } - *changed = true } } diff --git a/controllers/argocd/argocdcommon/image.go b/controllers/argocd/argocdcommon/image.go new file mode 100644 index 000000000..79fa6f344 --- /dev/null +++ b/controllers/argocd/argocdcommon/image.go @@ -0,0 +1,43 @@ +package argocdcommon + +import ( + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/util" +) + +// GetContainerImage is a general purpose function to retrieve the img and tag to be deployed for a given component. First priority is given to the CR spec field, which is calculated from the supplied instance and function. If CR spec does not specify an image, 2nd priority is given to an environment variable. If no env var is specified, or specified env var is not set, specified default img and tag values are returned +func GetContainerImage(f func(cr *argoproj.ArgoCD) (string, string), cr *argoproj.ArgoCD, envVar, defaultImg, defaultTag string) string { + img, tag := "", "" + + // set values defined in CR + img, tag = f(cr) + + if img == "" && tag == "" { + if envVar != "" { + // return image set in env var + if _, val := util.CaseInsensitiveGetenv(envVar); val != "" { + return val + } + } + } + + // return defaults if still unset + if img == "" { + img = defaultImg + } + + if tag == "" { + tag = defaultTag + } + + return util.CombineImageTag(img, tag) +} + +// GetArgoContainerImage will return the container image for given Argo CD instance +func GetArgoContainerImage(cr *argoproj.ArgoCD) string { + fn := func(cr *argoproj.ArgoCD) (string, string) { + return cr.Spec.Image, cr.Spec.Version + } + return GetContainerImage(fn, cr, common.ArgoCDImageEnvVar, common.ArgoCDDefaultArgoImage, common.ArgoCDDefaultArgoVersion) +} diff --git a/controllers/argocd/argocdcommon/secret.go b/controllers/argocd/argocdcommon/secret.go new file mode 100644 index 000000000..e6b9f82ec --- /dev/null +++ b/controllers/argocd/argocdcommon/secret.go @@ -0,0 +1,99 @@ +package argocdcommon + +import ( + "crypto/sha256" + "fmt" + "strings" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/networking" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// TLSSecretChecksum retrieves a specified TLS secret and calculates its checksum value and returns it. If a secret is determined to be of type other than TLS it returns an empty string +func TLSSecretChecksum(secretRef types.NamespacedName, client cntrlClient.Client) (string, error) { + var sha256sum string + + tlsSecret, err := workloads.GetSecret(secretRef.Name, secretRef.Namespace, client) + if err != nil { + return "", err + } + + if tlsSecret.Type != corev1.SecretTypeTLS { + // We only process secrets of type kubernetes.io/tls + return "", nil + } + + crt, crtOk := tlsSecret.Data[corev1.TLSCertKey] + key, keyOk := tlsSecret.Data[corev1.TLSPrivateKeyKey] + if crtOk && keyOk { + var sumBytes []byte + sumBytes = append(sumBytes, crt...) + sumBytes = append(sumBytes, key...) + sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) + } + return sha256sum, nil +} + +// FindSecretOwnerInstance finds the Argo CD instance that indirectly owns the given secret. It looks up a given secret, checks if it is owned by an Argo CD service or not. If yes, finds the Argo CD instance that owns the service and returns a reference to that instance +func FindSecretOwnerInstance(secretRef types.NamespacedName, client cntrlClient.Client) (types.NamespacedName, error) { + owner := types.NamespacedName{} + + secret, err := workloads.GetSecret(secretRef.Name, secretRef.Namespace, client) + if err != nil { + return types.NamespacedName{}, err + } + + secretOwnerRefs := secret.GetOwnerReferences() + if len(secretOwnerRefs) > 0 { + // OpenShift service CA sets the owner reference for the TLS secret to be a + // service, which in turn is owned by an Argo CD instance. This method performs + // a lookup of the instance through the intermediate owning service. + for _, secretOwner := range secretOwnerRefs { + if isOwnerOfInterest(secretOwner) { + owningSvc, err := networking.GetService(secretOwner.Name, secret.Namespace, client) + if err != nil { + return types.NamespacedName{}, err + } + + svcOwnerRefs := owningSvc.GetOwnerReferences() + for _, svcOwner := range svcOwnerRefs { + if svcOwner.Kind == common.ArgoCDKind { + owner.Name = svcOwner.Name + owner.Namespace = secret.Namespace + break + } + } + } + } + } else { + // For secrets without owner (i.e. manually created), we apply some + // heuristics. This may not be as accurate (e.g. if the user made a + // typo in the resource's name), but should be good enough for now. + if _, ok := secret.Annotations[common.ArgoCDArgoprojKeyName]; ok { + owner.Name = secret.Annotations[common.ArgoCDArgoprojKeyName] + owner.Namespace = secret.Annotations[common.ArgoCDArgoprojKeyNamespace] + } + } + return owner, nil +} + +// isOwnerOfInterest returns true if the given owner is one of the Argo CD services that +// may have been made the owner of the tls secret created by the OpenShift service CA, used +// to secure communication amongst the Argo CD components. +func isOwnerOfInterest(owner metav1.OwnerReference) bool { + if owner.Kind != common.ServiceKind { + return false + } + if strings.HasSuffix(owner.Name, common.RepoServerSuffix) { + return true + } + if strings.HasSuffix(owner.Name, common.RedisSuffix) { + return true + } + return false +} diff --git a/controllers/argocd/argocdcommon/testing.go b/controllers/argocd/argocdcommon/testing.go index dd5510ed7..11b5b0f50 100644 --- a/controllers/argocd/argocdcommon/testing.go +++ b/controllers/argocd/argocdcommon/testing.go @@ -12,7 +12,6 @@ import ( const ( TestNamespace = "argocd" TestArgoCDName = "argocd" - TestUID = "test-uid" ) var ( diff --git a/controllers/argocd/argocdcommon/workloads.go b/controllers/argocd/argocdcommon/workloads.go new file mode 100644 index 000000000..46d7585e2 --- /dev/null +++ b/controllers/argocd/argocdcommon/workloads.go @@ -0,0 +1,29 @@ +package argocdcommon + +import ( + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// TriggerDeploymentRollout will update the label with the given key to trigger a new rollout of the Deployment. +func TriggerDeploymentRollout(name, namespace, key string, client cntrlClient.Client) error { + deployment, err := workloads.GetDeployment(name, namespace, client) + if err != nil { + return err + } + + deployment.Spec.Template.ObjectMeta.Labels[key] = util.NowNano() + return workloads.UpdateDeployment(deployment, client) +} + +// TriggerStatefulSetRollout will update the label with the given key to trigger a new rollout of the StatefulSet. +func TriggerStatefulSetRollout(name, namespace, key string, client cntrlClient.Client) error { + statefulset, err := workloads.GetStatefulSet(name, namespace, client) + if err != nil { + return err + } + + statefulset.Spec.Template.ObjectMeta.Labels[key] = util.NowNano() + return workloads.UpdateStatefulSet(statefulset, client) +} diff --git a/controllers/argocd/notifications/configmap.go b/controllers/argocd/notifications/configmap.go index ab75376b7..c5b635e2b 100644 --- a/controllers/argocd/notifications/configmap.go +++ b/controllers/argocd/notifications/configmap.go @@ -28,6 +28,7 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { if err != nil { nr.Logger.Error(err, "reconcileConfigMap: failed to request configMap", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) + nr.Logger.V(1).Info("reconcileConfigMap: one or more mutations could not be applied") return err } diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index db5e360fd..8d5f75ee6 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -71,9 +71,6 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { }{ {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, func() { - if existingDeployment.Spec.Template.ObjectMeta.Labels == nil { - existingDeployment.Spec.Template.ObjectMeta.Labels = map[string]string{} - } existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, @@ -156,7 +153,7 @@ func (nr *NotificationsReconciler) getDesiredDeployment() *appsv1.Deployment { Command: nr.GetNotificationsCommand(), Image: argocdcommon.GetArgoContainerImage(nr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: resourceName, + Name: common.NotificationsControllerComponent, Env: notificationEnv, Resources: nr.GetNotificationsResources(), LivenessProbe: &corev1.Probe{ diff --git a/controllers/argocd/notifications/notifications_test.go b/controllers/argocd/notifications/notifications_test.go index 14e3f6954..c20331b2d 100644 --- a/controllers/argocd/notifications/notifications_test.go +++ b/controllers/argocd/notifications/notifications_test.go @@ -14,14 +14,14 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" ) -var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.NotificationsControllerComponent) +var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.ArgoCDNotificationsControllerComponent) func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *NotificationsReconciler { s := scheme.Scheme assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(common.NotificationsControllerComponent) + logger := ctrl.Log.WithName(common.ArgoCDNotificationsControllerComponent) return &NotificationsReconciler{ Client: cl, diff --git a/controllers/argocd/notifications/role.go b/controllers/argocd/notifications/role.go index 3cc86dc44..165f27446 100644 --- a/controllers/argocd/notifications/role.go +++ b/controllers/argocd/notifications/role.go @@ -33,6 +33,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { desiredRole, err := permissions.RequestRole(roleRequest) if err != nil { nr.Logger.Error(err, "reconcileRole: failed to request role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) + nr.Logger.V(1).Info("reconcileRole: one or more mutations could not be applied") return err } diff --git a/controllers/argocd/notifications/secret.go b/controllers/argocd/notifications/secret.go index 446652e4d..6b84f6ac0 100644 --- a/controllers/argocd/notifications/secret.go +++ b/controllers/argocd/notifications/secret.go @@ -30,6 +30,7 @@ func (nr *NotificationsReconciler) reconcileSecret() error { desiredSecret, err := workloads.RequestSecret(secretRequest) if err != nil { nr.Logger.Error(err, "reconcileSecret: failed to request secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + nr.Logger.V(1).Info("reconcileSecret: one or more mutations could not be applied") return err } diff --git a/pkg/argoutil/TOBEREMOVED.go b/pkg/argoutil/TOBEREMOVED.go index ba37f38df..594a08b08 100644 --- a/pkg/argoutil/TOBEREMOVED.go +++ b/pkg/argoutil/TOBEREMOVED.go @@ -2,20 +2,10 @@ package argoutil import ( "context" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "errors" "fmt" - "math" - "math/big" "sort" "strings" - "time" - tlsutil "github.com/operator-framework/operator-sdk/pkg/tls" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -27,105 +17,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" ) -// NewPrivateKey returns randomly generated RSA private key. -func NewPrivateKey() (*rsa.PrivateKey, error) { - return rsa.GenerateKey(rand.Reader, common.ArgoCDDefaultRSAKeySize) -} - -// EncodePrivateKeyPEM encodes the given private key pem and returns bytes (base64). -func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte { - return pem.EncodeToMemory(&pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(key), - }) -} - -// EncodeCertificatePEM encodes the given certificate pem and returns bytes (base64). -func EncodeCertificatePEM(cert *x509.Certificate) []byte { - return pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", - Bytes: cert.Raw, - }) -} - -// ParsePEMEncodedCert parses a certificate from the given pemdata -func ParsePEMEncodedCert(pemdata []byte) (*x509.Certificate, error) { - decoded, _ := pem.Decode(pemdata) - if decoded == nil { - return nil, errors.New("no PEM data found") - } - return x509.ParseCertificate(decoded.Bytes) -} - -// ParsePEMEncodedPrivateKey parses a private key from given pemdata -func ParsePEMEncodedPrivateKey(pemdata []byte) (*rsa.PrivateKey, error) { - decoded, _ := pem.Decode(pemdata) - if decoded == nil { - return nil, errors.New("no PEM data found") - } - return x509.ParsePKCS1PrivateKey(decoded.Bytes) -} - -// NewSelfSignedCACertificate returns a self-signed CA certificate based on given configuration and private key. -// The certificate has one-year lease. -func NewSelfSignedCACertificate(name string, key *rsa.PrivateKey) (*x509.Certificate, error) { - serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) - if err != nil { - return nil, err - } - now := time.Now() - tmpl := x509.Certificate{ - SerialNumber: serial, - NotBefore: now.UTC(), - NotAfter: now.Add(common.ArgoCDDuration365Days).UTC(), - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, - BasicConstraintsValid: true, - IsCA: true, - Subject: pkix.Name{CommonName: fmt.Sprintf("argocd-operator@%s", name)}, - } - certDERBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, key.Public(), key) - if err != nil { - return nil, err - } - return x509.ParseCertificate(certDERBytes) -} - -// NewSignedCertificate signs a certificate using the given private key, CA and returns a signed certificate. -// The certificate could be used for both client and server auth. -// The certificate has one-year lease. -func NewSignedCertificate(cfg *tlsutil.CertConfig, dnsNames []string, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) { - serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) - if err != nil { - return nil, err - } - eku := []x509.ExtKeyUsage{} - switch cfg.CertType { - case tlsutil.ClientCert: - eku = append(eku, x509.ExtKeyUsageClientAuth) - case tlsutil.ServingCert: - eku = append(eku, x509.ExtKeyUsageServerAuth) - case tlsutil.ClientAndServingCert: - eku = append(eku, x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth) - } - certTmpl := x509.Certificate{ - Subject: pkix.Name{ - CommonName: cfg.CommonName, - Organization: cfg.Organization, - }, - DNSNames: dnsNames, - SerialNumber: serial, - NotBefore: caCert.NotBefore, - NotAfter: time.Now().Add(common.ArgoCDDuration365Days).UTC(), - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: eku, - } - certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey) - if err != nil { - return nil, err - } - return x509.ParseCertificate(certDERBytes) -} - // EnvMerge merges two slices of EnvVar entries into a single one. If existing // has an EnvVar with same Name attribute as one in merge, the EnvVar is not // merged unless override is set to true. diff --git a/pkg/argoutil/resource.go b/pkg/argoutil/resource.go index 710a3dd8b..94f3dc91d 100644 --- a/pkg/argoutil/resource.go +++ b/pkg/argoutil/resource.go @@ -17,7 +17,10 @@ package argoutil import ( "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + argoprojv1alpha1 "github.com/argoproj-labs/argocd-operator/api/v1alpha1" + "github.com/argoproj-labs/argocd-operator/common" ) // FqdnServiceRef will return the FQDN referencing a specific service name, as set up by the operator, with the @@ -32,13 +35,22 @@ func NameWithSuffix(name, suffix string) string { } // GenerateResourceName generates names for namespace scoped resources -func GenerateResourceName(instanceName, component string) string { - return NameWithSuffix(instanceName, component) +func GenerateResourceName(instanceName, suffix string) string { + return NameWithSuffix(instanceName, suffix) } // GenerateUniqueResourceName generates unique names for cluster scoped resources -func GenerateUniqueResourceName(instanceName, instanceNamespace, component string) string { - return fmt.Sprintf("%s-%s-%s", instanceName, instanceNamespace, component) +func GenerateUniqueResourceName(instanceName, instanceNamespace, suffix string) string { + return fmt.Sprintf("%s-%s-%s", instanceName, instanceNamespace, suffix) +} + +func GetObjMeta(resName, resNs, instanceName, instanceNs, component string) metav1.ObjectMeta { + return metav1.ObjectMeta{ + Name: resName, + Namespace: resNs, + Labels: common.DefaultResourceLabels(resName, instanceName, component), + Annotations: common.DefaultResourceAnnotations(instanceName, instanceNs), + } } // FetchStorageSecretName will return the name of the Secret to use for the export process. diff --git a/pkg/argoutil/tls.go b/pkg/argoutil/tls.go new file mode 100644 index 000000000..24dfcd5dd --- /dev/null +++ b/pkg/argoutil/tls.go @@ -0,0 +1,136 @@ +// Copyright 2019 ArgoCD Operator Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package argoutil + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "errors" + "fmt" + "math" + "math/big" + "time" + + tlsutil "github.com/operator-framework/operator-sdk/pkg/tls" + + "github.com/argoproj-labs/argocd-operator/common" +) + +const ( + rsaPrivateKeyType = "RSA PRIVATE KEY" + certificateType = "CERTIFICATE" +) + +// NewPrivateKey returns randomly generated RSA private key. +func NewPrivateKey() (*rsa.PrivateKey, error) { + return rsa.GenerateKey(rand.Reader, common.ArgoCDDefaultRSAKeySize) +} + +// EncodePrivateKeyPEM encodes the given private key pem and returns bytes (base64). +func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte { + return pem.EncodeToMemory(&pem.Block{ + Type: rsaPrivateKeyType, + Bytes: x509.MarshalPKCS1PrivateKey(key), + }) +} + +// EncodeCertificatePEM encodes the given certificate pem and returns bytes (base64). +func EncodeCertificatePEM(cert *x509.Certificate) []byte { + return pem.EncodeToMemory(&pem.Block{ + Type: certificateType, + Bytes: cert.Raw, + }) +} + +// ParsePEMEncodedCert parses a certificate from the given pemdata +func ParsePEMEncodedCert(pemdata []byte) (*x509.Certificate, error) { + decoded, _ := pem.Decode(pemdata) + if decoded == nil { + return nil, errors.New("no PEM data found") + } + return x509.ParseCertificate(decoded.Bytes) +} + +// ParsePEMEncodedPrivateKey parses a private key from given pemdata +func ParsePEMEncodedPrivateKey(pemdata []byte) (*rsa.PrivateKey, error) { + decoded, _ := pem.Decode(pemdata) + if decoded == nil { + return nil, errors.New("no PEM data found") + } + return x509.ParsePKCS1PrivateKey(decoded.Bytes) +} + +// NewSelfSignedCACertificate returns a self-signed CA certificate based on given configuration and private key. +// The certificate has one-year lease. +func NewSelfSignedCACertificate(name string, key *rsa.PrivateKey) (*x509.Certificate, error) { + serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) + if err != nil { + return nil, err + } + now := time.Now() + tmpl := x509.Certificate{ + SerialNumber: serial, + NotBefore: now.UTC(), + NotAfter: now.Add(common.ArgoCDDuration365Days).UTC(), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, + BasicConstraintsValid: true, + IsCA: true, + Subject: pkix.Name{CommonName: fmt.Sprintf("argocd-operator@%s", name)}, + } + certDERBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, key.Public(), key) + if err != nil { + return nil, err + } + return x509.ParseCertificate(certDERBytes) +} + +// NewSignedCertificate signs a certificate using the given private key, CA and returns a signed certificate. +// The certificate could be used for both client and server auth. +// The certificate has one-year lease. +func NewSignedCertificate(cfg *tlsutil.CertConfig, dnsNames []string, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) { + serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) + if err != nil { + return nil, err + } + eku := []x509.ExtKeyUsage{} + switch cfg.CertType { + case tlsutil.ClientCert: + eku = append(eku, x509.ExtKeyUsageClientAuth) + case tlsutil.ServingCert: + eku = append(eku, x509.ExtKeyUsageServerAuth) + case tlsutil.ClientAndServingCert: + eku = append(eku, x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth) + } + certTmpl := x509.Certificate{ + Subject: pkix.Name{ + CommonName: cfg.CommonName, + Organization: cfg.Organization, + }, + DNSNames: dnsNames, + SerialNumber: serial, + NotBefore: caCert.NotBefore, + NotAfter: time.Now().Add(common.ArgoCDDuration365Days).UTC(), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: eku, + } + certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey) + if err != nil { + return nil, err + } + return x509.ParseCertificate(certDERBytes) +} diff --git a/pkg/cluster/event.go b/pkg/cluster/event.go index ee3f082eb..3a1b4f343 100644 --- a/pkg/cluster/event.go +++ b/pkg/cluster/event.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/mutation" ) @@ -23,10 +24,13 @@ type EventRequest struct { CreationTimestamp metav1.Time FirstTimestamp metav1.Time LastTimestamp metav1.Time + Instance *argoproj.ArgoCD // array of functions to mutate event before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } func newEvent(objMeta metav1.ObjectMeta, typeMeta metav1.TypeMeta, eventType, action, message, reason string) *corev1.Event { @@ -61,7 +65,7 @@ func RequestEvent(request EventRequest) (*corev1.Event, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, event, request.Client) + err := mutation(request.Instance, event, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/cluster/namespace.go b/pkg/cluster/namespace.go index ffcbf17b0..5abfd58d8 100644 --- a/pkg/cluster/namespace.go +++ b/pkg/cluster/namespace.go @@ -10,6 +10,7 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -17,10 +18,13 @@ import ( type NamespaceRequest struct { ObjectMeta metav1.ObjectMeta Spec corev1.NamespaceSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } func newNamespace(objMeta metav1.ObjectMeta, spec corev1.NamespaceSpec) *corev1.Namespace { @@ -40,7 +44,7 @@ func RequestNamespace(request NamespaceRequest) (*corev1.Namespace, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, namespace, request.Client) + err := mutation(request.Instance, namespace, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/cluster/namespace_test.go b/pkg/cluster/namespace_test.go index 71f795509..a2743e2a7 100644 --- a/pkg/cluster/namespace_test.go +++ b/pkg/cluster/namespace_test.go @@ -36,11 +36,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *corev1.Namespace: if _, ok := obj.Labels[testKey]; ok { diff --git a/pkg/monitoring/monitoring_test.go b/pkg/monitoring/monitoring_test.go index 64ff1e1e2..834b1c34c 100644 --- a/pkg/monitoring/monitoring_test.go +++ b/pkg/monitoring/monitoring_test.go @@ -26,11 +26,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *monitoringv1.PrometheusRule: obj.Name = testPrometheusRuleNameMutated diff --git a/pkg/monitoring/prometheusRule.go b/pkg/monitoring/prometheusRule.go index 1d4d8f9a9..f3cbf02a4 100644 --- a/pkg/monitoring/prometheusRule.go +++ b/pkg/monitoring/prometheusRule.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -17,9 +18,13 @@ type PrometheusRuleRequest struct { ObjectMeta metav1.ObjectMeta Spec monitoringv1.PrometheusRuleSpec - // array of functions to mutate role before returning to requester + Instance *argoproj.ArgoCD + + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newPrometheusRule returns a new PrometheusRule instance for the given ArgoCD. @@ -38,7 +43,7 @@ func RequestPrometheusRule(request PrometheusRuleRequest) (*monitoringv1.Prometh if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, prometheusRule, request.Client) + err := mutation(request.Instance, prometheusRule, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/monitoring/serviceMonitor.go b/pkg/monitoring/serviceMonitor.go index adcf54a34..1d231684a 100644 --- a/pkg/monitoring/serviceMonitor.go +++ b/pkg/monitoring/serviceMonitor.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type ServiceMonitorRequest struct { ObjectMeta metav1.ObjectMeta Spec monitoringv1.ServiceMonitorSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newServiceMonitor returns a new ServiceMonitor instance for the given ArgoCD. @@ -38,7 +42,7 @@ func RequestServiceMonitor(request ServiceMonitorRequest) (*monitoringv1.Service if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, serviceMonitor, request.Client) + err := mutation(request.Instance, serviceMonitor, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/mutation/mutation.go b/pkg/mutation/mutation.go index 24c32a6cf..307db7746 100644 --- a/pkg/mutation/mutation.go +++ b/pkg/mutation/mutation.go @@ -14,7 +14,7 @@ var ( ) // MutateFunc defines the function signature for any mutation functions that need to be executed by this package -type MutateFunc func(*argoproj.ArgoCD, interface{}, client.Client) error +type MutateFunc func(*argoproj.ArgoCD, interface{}, client.Client, ...interface{}) error // Register adds a modifier for updating resources during reconciliation. func Register(m ...MutateFunc) { @@ -23,11 +23,11 @@ func Register(m ...MutateFunc) { mutateFuncs = append(mutateFuncs, m...) } -func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client client.Client) error { +func ApplyReconcilerMutation(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { mutex.Lock() defer mutex.Unlock() for _, mutateFunc := range mutateFuncs { - if err := mutateFunc(cr, resource, client); err != nil { + if err := mutateFunc(cr, resource, client, args...); err != nil { return err } } diff --git a/pkg/networking/ingress.go b/pkg/networking/ingress.go index 25bdda9db..a660ce22d 100644 --- a/pkg/networking/ingress.go +++ b/pkg/networking/ingress.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type IngressRequest struct { ObjectMeta metav1.ObjectMeta Spec networkingv1.IngressSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newIngress returns a new Ingress instance for the given ArgoCD. @@ -38,7 +42,7 @@ func RequestIngress(request IngressRequest) (*networkingv1.Ingress, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, ingress, request.Client) + err := mutation(request.Instance, ingress, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/networking/networking_test.go b/pkg/networking/networking_test.go index 3aaaa37a9..449fc36f8 100644 --- a/pkg/networking/networking_test.go +++ b/pkg/networking/networking_test.go @@ -30,11 +30,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *corev1.Service: obj.Name = testServiceNameMutated diff --git a/pkg/networking/service.go b/pkg/networking/service.go index d4b21df26..d5b72858a 100644 --- a/pkg/networking/service.go +++ b/pkg/networking/service.go @@ -10,16 +10,21 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) // ServiceRequest objects contain all the required information to produce a service object in return type ServiceRequest struct { ObjectMeta metav1.ObjectMeta Spec corev1.ServiceSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newService returns a new Service instance for the given ArgoCD. @@ -38,7 +43,7 @@ func RequestService(request ServiceRequest) (*corev1.Service, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, service, request.Client) + err := mutation(request.Instance, service, request.Client, request.MutationArgs...) if err != nil { mutationErr = err } diff --git a/pkg/openshift/mutation.go b/pkg/openshift/mutation.go index 20f1728e2..20e812b59 100644 --- a/pkg/openshift/mutation.go +++ b/pkg/openshift/mutation.go @@ -8,34 +8,158 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/pkg/errors" + appsv1 "k8s.io/api/apps/v1" + rbacv1 "k8s.io/api/rbac/v1" ) func init() { mutation.Register(AddSeccompProfileForOpenShift) + mutation.Register(AddNonRootSCCForOpenShift) + mutation.Register(AddAutoTLSAnnotationForOpenShift) } -func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client) error { +// TO DO: Add dedicated e2e tests for all these mutations + +// AddAutoTLSAnnotationForOpenShift adds the OpenShift Service CA TLS cert request annotaiton to the provided service object, using the provided secret name as the value +func AddAutoTLSAnnotationForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { if !IsOpenShiftEnv() { return nil } switch obj := resource.(type) { - case *corev1.PodSpec: + case *corev1.Service: + if cr == nil { + return nil + } + // return if autoTLS is not requested + if !cr.Spec.Redis.WantsAutoTLS() { + return nil + } + + if obj.Annotations == nil { + obj.Annotations = make(map[string]string) + } + + // Ensure that args carries only one argument, which is a map of type map[string]string + // containing the key "tls-secret-name". If this is the case, the associated value + // can be used within the service annotation + if len(args) == 1 { + for _, arg := range args { + argMap := arg.(map[string]string) + if val, ok := argMap[common.TLSSecretNameKey]; ok { + obj.Annotations[common.ServiceBetaOpenshiftKeyCertSecret] = val + } + } + } + } + return nil +} + +func AddSeccompProfileForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { + if !IsOpenShiftEnv() { + return nil + } + + addSeccompProfile := func(podSpec *corev1.PodSpec) error { + if !IsVersionAPIAvailable() { + return nil + } version, err := GetClusterVersion(client) if err != nil { - return err + return errors.Wrapf(err, "AddSeccompProfileForOpenShift: failed to retrieve OpenShift cluster version") } + if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 { - if obj.SecurityContext == nil { - obj.SecurityContext = &corev1.PodSecurityContext{} + if podSpec.SecurityContext == nil { + podSpec.SecurityContext = &corev1.PodSecurityContext{} } - if obj.SecurityContext.SeccompProfile == nil { - obj.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} + if podSpec.SecurityContext.SeccompProfile == nil { + podSpec.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} } - if len(obj.SecurityContext.SeccompProfile.Type) == 0 { - obj.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault + if len(podSpec.SecurityContext.SeccompProfile.Type) == 0 { + podSpec.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault } + + containers := []corev1.Container{} + for _, container := range podSpec.Containers { + if container.SecurityContext.SeccompProfile == nil { + container.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} + } + if len(container.SecurityContext.SeccompProfile.Type) == 0 { + container.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault + } + containers = append(containers, container) + } + podSpec.Containers = containers + + initContainers := []corev1.Container{} + for _, initc := range podSpec.InitContainers { + if initc.SecurityContext.SeccompProfile == nil { + initc.SecurityContext.SeccompProfile = &corev1.SeccompProfile{} + } + if len(initc.SecurityContext.SeccompProfile.Type) == 0 { + initc.SecurityContext.SeccompProfile.Type = corev1.SeccompProfileTypeRuntimeDefault + } + initContainers = append(initContainers, initc) + } + podSpec.InitContainers = initContainers + } + return nil } + + switch obj := resource.(type) { + case *appsv1.StatefulSet: + return addSeccompProfile(&obj.Spec.Template.Spec) + case *appsv1.Deployment: + return addSeccompProfile(&obj.Spec.Template.Spec) + } + return nil +} + +func AddNonRootSCCForOpenShift(cr *argoproj.ArgoCD, resource interface{}, client client.Client, args ...interface{}) error { + if !IsOpenShiftEnv() { + return nil + } + switch obj := resource.(type) { + case *rbacv1.Role: + // This mutation only applies to redis and redis-ha roles + if component, ok := obj.Labels[common.AppK8sKeyComponent]; !ok || (ok && component != common.RedisComponent) { + return nil + } + + if !IsVersionAPIAvailable() { + return nil + } + // Starting with OpenShift 4.11, we need to use the resource name "nonroot-v2" instead of "nonroot" + resourceName := "nonroot" + version, err := GetClusterVersion(client) + if err != nil { + return errors.Wrapf(err, "AppendNonRootSCCForOpenShift: failed to retrieve OpenShift cluster version") + } + + if version == "" || semver.Compare(fmt.Sprintf("v%s", version), "v4.10.999") > 0 { + resourceName = "nonroot-v2" + } + + orules := rbacv1.PolicyRule{ + APIGroups: []string{ + "security.openshift.io", + }, + ResourceNames: []string{ + resourceName, + }, + Resources: []string{ + "securitycontextconstraints", + }, + Verbs: []string{ + "use", + }, + } + obj.Rules = append(obj.Rules, orules) + } + return nil } diff --git a/pkg/openshift/networking.go b/pkg/openshift/networking.go index 697d5554b..6f1f329ee 100644 --- a/pkg/openshift/networking.go +++ b/pkg/openshift/networking.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" @@ -39,10 +40,13 @@ func VerifyRouteAPI() error { type RouteRequest struct { ObjectMeta metav1.ObjectMeta Spec routev1.RouteSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newRoute returns a new Route instance for the given ArgoCD. @@ -61,7 +65,7 @@ func RequestRoute(request RouteRequest) (*routev1.Route, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, route, request.Client) + err := mutation(request.Instance, route, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/openshift/openshift_test.go b/pkg/openshift/openshift_test.go index 7f8cb67af..e6aebd238 100644 --- a/pkg/openshift/openshift_test.go +++ b/pkg/openshift/openshift_test.go @@ -27,11 +27,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *oappsv1.DeploymentConfig: obj.Name = testNameMutated diff --git a/pkg/openshift/workloads.go b/pkg/openshift/workloads.go index 2851faf43..69b06a8f8 100644 --- a/pkg/openshift/workloads.go +++ b/pkg/openshift/workloads.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type DeploymentConfigRequest struct { ObjectMeta metav1.ObjectMeta Spec oappsv1.DeploymentConfigSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newDeploymentConfig returns a new DeploymentConfig instance for the given ArgoCD. @@ -37,7 +41,7 @@ func RequestDeploymentConfig(request DeploymentConfigRequest) (*oappsv1.Deployme deploymentConfig := newDeploymentConfig(request.ObjectMeta, request.Spec) if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, deploymentConfig, request.Client) + err := mutation(request.Instance, deploymentConfig, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/permissions/clusterrole.go b/pkg/permissions/clusterrole.go index 9a1f016f3..1f401e92f 100644 --- a/pkg/permissions/clusterrole.go +++ b/pkg/permissions/clusterrole.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type ClusterRoleRequest struct { ObjectMeta metav1.ObjectMeta Rules []rbacv1.PolicyRule + Instance *argoproj.ArgoCD // array of functions to mutate clusterRole before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newClusterRole returns a new clusterRole instance. @@ -41,7 +45,7 @@ func RequestClusterRole(request ClusterRoleRequest) (*rbacv1.ClusterRole, error) if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, clusterRole, request.Client) + err := mutation(request.Instance, clusterRole, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/permissions/permissions_test.go b/pkg/permissions/permissions_test.go index 5bfc8ceb6..f3b920f57 100644 --- a/pkg/permissions/permissions_test.go +++ b/pkg/permissions/permissions_test.go @@ -62,11 +62,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *rbacv1.Role: if obj.Namespace == testNamespace { diff --git a/pkg/permissions/role.go b/pkg/permissions/role.go index 83b1b436c..97f9fa361 100644 --- a/pkg/permissions/role.go +++ b/pkg/permissions/role.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type RoleRequest struct { ObjectMeta metav1.ObjectMeta Rules []rbacv1.PolicyRule + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newRole returns a new Role instance. @@ -40,7 +44,7 @@ func RequestRole(request RoleRequest) (*rbacv1.Role, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, role, request.Client) + err := mutation(request.Instance, role, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/resource/clusterScoped.go b/pkg/resource/clusterScoped.go index 9068305f4..cb10a00e0 100644 --- a/pkg/resource/clusterScoped.go +++ b/pkg/resource/clusterScoped.go @@ -4,6 +4,7 @@ import ( "context" types "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/retry" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -34,17 +35,24 @@ func ListClusterObjects(objList cntrlClient.ObjectList, client cntrlClient.Clien // UpdateClusterObject updates the specified object using the provided client. func UpdateClusterObject(obj cntrlClient.Object, client cntrlClient.Client) error { - existingObj, err := GetClusterObject(obj.GetName(), obj, client) - if err != nil { - return err - } + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + existingObj, err := GetClusterObject(obj.GetName(), obj, client) + if err != nil { + return err + } - obj.SetResourceVersion(existingObj.GetResourceVersion()) + obj.SetResourceVersion(existingObj.GetResourceVersion()) - if err = client.Update(context.TODO(), obj); err != nil { + if err = client.Update(context.TODO(), obj); err != nil { + return err + } + return nil + }) + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error return err } - return nil } diff --git a/pkg/resource/namespaceScoped.go b/pkg/resource/namespaceScoped.go index c0fd0f6ca..7c74f8d30 100644 --- a/pkg/resource/namespaceScoped.go +++ b/pkg/resource/namespaceScoped.go @@ -4,6 +4,7 @@ import ( "context" types "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/util/retry" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -35,17 +36,24 @@ func ListObjects(namespace string, objList cntrlClient.ObjectList, client cntrlC // UpdateObject updates the specified object using the provided client. func UpdateObject(obj cntrlClient.Object, client cntrlClient.Client) error { - existingObj, err := GetObject(obj.GetName(), obj.GetNamespace(), obj, client) - if err != nil { - return err - } + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + existingObj, err := GetObject(obj.GetName(), obj.GetNamespace(), obj, client) + if err != nil { + return err + } - obj.SetResourceVersion(existingObj.GetResourceVersion()) + obj.SetResourceVersion(existingObj.GetResourceVersion()) - if err = client.Update(context.TODO(), obj); err != nil { + if err = client.Update(context.TODO(), obj); err != nil { + return err + } + return nil + }) + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error return err } - return nil } diff --git a/pkg/util/error.go b/pkg/util/error.go new file mode 100644 index 000000000..f4f1c20ef --- /dev/null +++ b/pkg/util/error.go @@ -0,0 +1,63 @@ +package util + +import ( + "errors" +) + +// MultiError employs the generic error interface but allows storage of a slice of errors +type MultiError struct { + Errs []error +} + +// Split returns the slice of collected errors +func (e *MultiError) Split() []error { + return e.Errs +} + +func (e MultiError) Error() string { + if e.IsNil() { + return "" + } + return errors.Join(e.Errs...).Error() +} + +// Append adds errors to the slice. Nil errors are filtered out. +// Errors are not flattened out +func (e *MultiError) Append(errs ...error) { + for _, err := range errs { + if err == nil { + continue + } + e.Errs = append(e.Errs, err) + } +} + +// Flatten recursively flattens out a MultiError +func (e *MultiError) Flatten() []error { + var flattenedErrors []error = make([]error, 0) + + for _, err := range e.Errs { + if subMultiErr, ok := err.(*MultiError); ok { + // If the error is a MultiError, recursively flatten it + flattenedErrors = append(flattenedErrors, subMultiErr.Flatten()...) + } else { + // Otherwise, add the error to the flattened list + flattenedErrors = append(flattenedErrors, err) + } + } + + return flattenedErrors +} + +// IsNil determins if the MultiError by checking if the length of the error slice is 0 or not +func (e *MultiError) IsNil() bool { + return len(e.Errs) == 0 +} + +// ErrOrNil returns nil if the given error is determined to be nil, else it returns the error itself +func (e *MultiError) ErrOrNil() error { + if e.IsNil() { + return nil + } + return e +} diff --git a/pkg/util/error_test.go b/pkg/util/error_test.go new file mode 100644 index 000000000..24cc7ca55 --- /dev/null +++ b/pkg/util/error_test.go @@ -0,0 +1,214 @@ +package util + +import ( + "errors" + "reflect" + "testing" +) + +func TestMultiError_Split(t *testing.T) { + tests := []struct { + name string + multiErr *MultiError + expected []error + }{ + { + "Basic split", + &MultiError{Errs: []error{errors.New("error1"), errors.New("error2")}}, + []error{errors.New("error1"), errors.New("error2")}, + }, + { + "split Empty", + &MultiError{Errs: []error{}}, + []error{}, + }, + { + "split MultiError", + &MultiError{Errs: []error{errors.New("error1"), &MultiError{Errs: []error{errors.New("error2"), errors.New("error3")}}}}, + []error{errors.New("error1"), &MultiError{Errs: []error{errors.New("error2"), errors.New("error3")}}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.multiErr.Split() + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("Unwrap() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestMultiError_Error(t *testing.T) { + tests := []struct { + name string + multiErr *MultiError + expected string + }{ + { + "Basic Error", + &MultiError{Errs: []error{errors.New("error1"), errors.New("error2")}}, + "error1\nerror2", + }, + { + "Error Empty", + &MultiError{Errs: []error{}}, + "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.multiErr.Error() + if got != tt.expected { + t.Errorf("Error() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestMultiError_Append(t *testing.T) { + tests := []struct { + name string + multiErr *MultiError + errors []error + expected []error + }{ + { + "Basic Append", + &MultiError{Errs: []error{errors.New("error1")}}, + []error{errors.New("error2")}, + []error{errors.New("error1"), errors.New("error2")}, + }, + { + "Append Nil Error", + &MultiError{Errs: []error{errors.New("error1")}}, + []error{nil, errors.New("error2")}, + []error{errors.New("error1"), errors.New("error2")}, + }, + { + "Append MultiError", + &MultiError{Errs: []error{errors.New("error1")}}, + []error{&MultiError{Errs: []error{errors.New("error2"), errors.New("error3")}}}, + []error{errors.New("error1"), &MultiError{Errs: []error{errors.New("error2"), errors.New("error3")}}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.multiErr.Append(tt.errors...) + + got := tt.multiErr.Split() + + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("Append() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestMultiError_Flatten(t *testing.T) { + tests := []struct { + name string + multiErr *MultiError + expected []error + }{ + { + "Basic Flatten", + &MultiError{Errs: []error{errors.New("error1"), errors.New("error2")}}, + []error{errors.New("error1"), errors.New("error2")}, + }, + { + "Flatten Nested MultiError", + &MultiError{Errs: []error{errors.New("error1"), &MultiError{Errs: []error{errors.New("error2"), errors.New("error3")}}}}, + []error{errors.New("error1"), errors.New("error2"), errors.New("error3")}, + }, + { + "Flatten Empty MultiError", + &MultiError{Errs: []error{}}, + []error{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.multiErr.Flatten() + + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("Flatten() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestMultiError_IsNil(t *testing.T) { + tests := []struct { + name string + multiErr *MultiError + expected bool + }{ + { + "IsNil True", + &MultiError{Errs: []error{}}, + true, + }, + { + "IsNil False", + &MultiError{Errs: []error{errors.New("error1")}}, + false, + }, + { + "IsNil MultiError", + &MultiError{Errs: []error{&MultiError{Errs: []error{errors.New("error2")}}}}, + false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.multiErr.IsNil() + + if got != tt.expected { + t.Errorf("IsNil() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestMultiError_ErrOrNil(t *testing.T) { + + testME := MultiError{Errs: []error{errors.New("error1")}} + testMultiME := MultiError{Errs: []error{&MultiError{Errs: []error{errors.New("error2")}}}} + + tests := []struct { + name string + multiErr *MultiError + expected error + }{ + { + "ErrOrNil Nil", + &MultiError{Errs: []error{}}, + nil, + }, + { + "ErrOrNil Non-Nil", + &testME, + &testME, + }, + { + "ErrOrNil MultiError", + &testMultiME, + &testMultiME, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.multiErr.ErrOrNil() + + if got != tt.expected { + t.Errorf("ErrOrNil() = %v, want %v", got, tt.expected) + } + }) + } +} diff --git a/pkg/util/image.go b/pkg/util/image.go index 3dea02ecc..56a2aa82c 100644 --- a/pkg/util/image.go +++ b/pkg/util/image.go @@ -7,6 +7,10 @@ import ( // CombineImageTag will return the combined image and tag in the proper format for tags and digests. func CombineImageTag(img string, tag string) string { + if img == "" { + return tag + } + if strings.Contains(tag, ":") { return fmt.Sprintf("%s@%s", img, tag) // Digest } else if len(tag) > 0 { diff --git a/pkg/util/image_test.go b/pkg/util/image_test.go new file mode 100644 index 000000000..e726cffe5 --- /dev/null +++ b/pkg/util/image_test.go @@ -0,0 +1,53 @@ +package util + +import "testing" + +func TestCombineImageTag(t *testing.T) { + tests := []struct { + name string + img string + tag string + expected string + }{ + { + "CombineImageTag Tag", + "my-image", + "latest", + "my-image:latest", + }, + { + "CombineImageTag Digest", + "my-image", + "sha256:abc123", + "my-image@sha256:abc123", + }, + { + "CombineImageTag NoTag", + "my-image", + "", + "my-image", + }, + { + "CombineImageTag Tag With Colon", + "my-image", + "v1.0:20220101", + "my-image@v1.0:20220101", + }, + { + "CombineImageTag Empty Image", + "", + "latest", + "latest", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := CombineImageTag(tt.img, tt.tag) + + if got != tt.expected { + t.Errorf("CombineImageTag() = %v, want %v", got, tt.expected) + } + }) + } +} diff --git a/pkg/util/int.go b/pkg/util/int.go index e305666d9..9bab50585 100644 --- a/pkg/util/int.go +++ b/pkg/util/int.go @@ -1,5 +1,10 @@ package util +// Int32Ptr returns a pointer to the provided int32 value +func Int32Ptr(val int32) *int32 { + return &val +} + // Int64Ptr returns a pointer to the provided int64 value func Int64Ptr(val int64) *int64 { return &val diff --git a/pkg/util/interface.go b/pkg/util/interface.go new file mode 100644 index 000000000..8357f92e7 --- /dev/null +++ b/pkg/util/interface.go @@ -0,0 +1,36 @@ +package util + +import "reflect" + +// ConvertStringsToInterfaces accepts a slice to strings and converts it into a slice to interfaces +func ConvertStringsToInterfaces(str ...string) []interface{} { + s := make([]interface{}, len(str)) + for i, v := range str { + s[i] = v + } + return s +} + +func ConvertStringMapToInterfaces(val ...map[string]string) []interface{} { + s := make([]interface{}, len(val)) + for i, v := range val { + s[i] = v + } + return s +} + +// IsPtr tells us if a provided interface is a pointer or not +func IsPtr(i interface{}) bool { + if i == nil { + return false + } + return reflect.ValueOf(i).Type().Kind() == reflect.Ptr +} + +// IsSlice tells us if a provided interface is a slice or not +func IsSlice(i interface{}) bool { + if i == nil { + return false + } + return reflect.ValueOf(i).Type().Kind() == reflect.Slice +} diff --git a/pkg/util/interface_test.go b/pkg/util/interface_test.go new file mode 100644 index 000000000..da625296c --- /dev/null +++ b/pkg/util/interface_test.go @@ -0,0 +1,142 @@ +package util + +import ( + "reflect" + "testing" +) + +func TestConvertStringsToInterfaces(t *testing.T) { + tests := []struct { + name string + str []string + expected []interface{} + }{ + { + "ConvertStringsToInterfaces Basic", + []string{"apple", "banana", "orange"}, + []interface{}{"apple", "banana", "orange"}, + }, + { + "ConvertStringsToInterfaces Empty", + []string{}, + []interface{}{}, + }, + { + "ConvertStringsToInterfaces With Spaces", + []string{"apple", "banana ", " orange"}, + []interface{}{"apple", "banana ", " orange"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := ConvertStringsToInterfaces(tt.str...) + + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("ConvertStringsToInterfaces() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestConvertStringMapToInterfaces(t *testing.T) { + tests := []struct { + name string + val []map[string]string + expected []interface{} + }{ + { + "ConvertStringMapToInterfaces Basic", + []map[string]string{{"key1": "value1"}, {"key2": "value2"}}, + []interface{}{map[string]string{"key1": "value1"}, map[string]string{"key2": "value2"}}, + }, + { + "ConvertStringMapToInterfaces Empty", + []map[string]string{}, + []interface{}{}, + }, + { + "ConvertStringMapToInterfaces With Empty Map", + []map[string]string{{}, {"key": "value"}}, + []interface{}{map[string]string{}, map[string]string{"key": "value"}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := ConvertStringMapToInterfaces(tt.val...) + + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("ConvertStringMapToInterfaces() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestIsPtr(t *testing.T) { + tests := []struct { + name string + input interface{} + expected bool + }{ + { + "IsPtr True", + &struct{}{}, + true, + }, + { + "IsPtr False", + struct{}{}, + false, + }, + { + "IsPtr Nil", + nil, + false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := IsPtr(tt.input) + + if got != tt.expected { + t.Errorf("IsPtr() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestIsSlice(t *testing.T) { + tests := []struct { + name string + input interface{} + expected bool + }{ + { + "IsSlice True", + []int{1, 2, 3}, + true, + }, + { + "IsSlice False", + 42, + false, + }, + { + "IsSlice Nil", + nil, + false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := IsSlice(tt.input) + + if got != tt.expected { + t.Errorf("IsSlice() = %v, want %v", got, tt.expected) + } + }) + } +} diff --git a/pkg/util/log.go b/pkg/util/log.go new file mode 100644 index 000000000..f0cf226d1 --- /dev/null +++ b/pkg/util/log.go @@ -0,0 +1,22 @@ +package util + +import ( + "strings" + + "go.uber.org/zap/zapcore" +) + +func GetLogLevel(lvl string) zapcore.Level { + switch strings.ToLower(lvl) { + case "error": + return zapcore.ErrorLevel + case "warn": + return zapcore.WarnLevel + case "info": + return zapcore.InfoLevel + case "debug": + return zapcore.DebugLevel + default: + return zapcore.InfoLevel + } +} diff --git a/pkg/util/log_test.go b/pkg/util/log_test.go new file mode 100644 index 000000000..47fded774 --- /dev/null +++ b/pkg/util/log_test.go @@ -0,0 +1,56 @@ +package util + +import ( + "testing" + + "go.uber.org/zap/zapcore" +) + +func TestGetLogLevel(t *testing.T) { + tests := []struct { + name string + lvl string + expected zapcore.Level + }{ + { + "GetLogLevel Error", + "error", + zapcore.ErrorLevel, + }, + { + "GetLogLevel Warn", + "warn", + zapcore.WarnLevel, + }, + { + "GetLogLevel Info", + "info", + zapcore.InfoLevel, + }, + { + "GetLogLevel Debug", + "debug", + zapcore.DebugLevel, + }, + { + "GetLogLevel Default", + "unknown", + zapcore.InfoLevel, + }, + { + "GetLogLevel Mixed Case", + "DeBuG", + zapcore.DebugLevel, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := GetLogLevel(tt.lvl) + + if got != tt.expected { + t.Errorf("GetLogLevel() = %v, want %v", got, tt.expected) + } + }) + } +} diff --git a/pkg/util/map_test.go b/pkg/util/map_test.go new file mode 100644 index 000000000..23953d8ad --- /dev/null +++ b/pkg/util/map_test.go @@ -0,0 +1,93 @@ +package util + +import ( + "reflect" + "sort" + "testing" +) + +func TestMergeMaps(t *testing.T) { + tests := []struct { + name string + mapA map[string]string + mapB map[string]string + expected map[string]string + }{ + { + "Basic Merge", + map[string]string{"key1": "value1", "key2": "value2"}, + map[string]string{"key2": "new_value2", "key3": "value3"}, + map[string]string{"key1": "value1", "key2": "new_value2", "key3": "value3"}, + }, + { + "Empty Maps", + map[string]string{}, + map[string]string{}, + map[string]string{}, + }, + { + "Conflict Resolution (B Overwrites A)", + map[string]string{"key1": "value1", "key2": "value2"}, + map[string]string{"key2": "new_value2", "key1": "new_value1"}, + map[string]string{"key1": "new_value1", "key2": "new_value2"}, + }, + { + "Maps with Different Types", + map[string]string{"key1": "value1", "key2": "value2"}, + map[string]string{"key3": "value3", "key4": "value4"}, + map[string]string{"key1": "value1", "key2": "value2", "key3": "value3", "key4": "value4"}, + }, + { + "Map B Overrides Empty Map A", + map[string]string{}, + map[string]string{"key1": "value1", "key2": "value2"}, + map[string]string{"key1": "value1", "key2": "value2"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := MergeMaps(tt.mapA, tt.mapB) + + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("MergeMaps() = %v, want %v", got, tt.expected) + } + }) + } +} + +func TestStringMapKeys(t *testing.T) { + tests := []struct { + name string + inputMap map[string]string + expected []string + }{ + { + "Basic String Keys", + map[string]string{"key3": "value3", "key1": "value1", "key2": "value2"}, + []string{"key1", "key2", "key3"}, + }, + { + "Empty Map", + map[string]string{}, + []string{}, + }, + { + "Map with Single Key", + map[string]string{"single_key": "value"}, + []string{"single_key"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := StringMapKeys(tt.inputMap) + + sort.Strings(got) // Sorting for consistent comparison + + if !reflect.DeepEqual(got, tt.expected) { + t.Errorf("StringMapKeys() = %v, want %v", got, tt.expected) + } + }) + } +} diff --git a/pkg/util/string.go b/pkg/util/string.go index 73a93f092..f456e8d69 100644 --- a/pkg/util/string.go +++ b/pkg/util/string.go @@ -8,6 +8,9 @@ import ( // SplitList accepts a string input containing a list of comma separated values, and returns a slice containing those values as separate elements func SplitList(s string) []string { + if s == "" { + return []string{} + } elems := strings.Split(s, ",") for i := range elems { elems[i] = strings.TrimSpace(elems[i]) @@ -18,6 +21,10 @@ func SplitList(s string) []string { // RemoveString removes the given string from the given slice func RemoveString(slice []string, s string) []string { var result []string + if len(slice) == 0 { + return []string{} + } + for _, item := range slice { if item == s { continue @@ -38,13 +45,15 @@ func ContainsString(arr []string, s string) bool { } func Equal(a, b []string) bool { - sort.Strings(a) - sort.Strings(b) - if len(a) != len(b) { + s1 := append([]string{}, a...) + s2 := append([]string{}, b...) + sort.Strings(s1) + sort.Strings(s2) + if len(s1) != len(s2) { return false } - for i := range a { - if a[i] != b[i] { + for i := range s1 { + if s1[i] != s2[i] { return false } } diff --git a/pkg/util/string_test.go b/pkg/util/string_test.go new file mode 100644 index 000000000..5ecbc9cb9 --- /dev/null +++ b/pkg/util/string_test.go @@ -0,0 +1,141 @@ +package util + +import ( + "encoding/base64" + "reflect" + "testing" +) + +func TestSplitList(t *testing.T) { + tests := []struct { + name string + s string + want []string + }{ + {"Empty string", "", []string{}}, + {"Single element", "apple", []string{"apple"}}, + {"Comma-separated values", "apple,banana,orange", []string{"apple", "banana", "orange"}}, + {"Trim spaces", " apple , banana , orange ", []string{"apple", "banana", "orange"}}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := SplitList(tt.s) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("SplitList() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRemoveString(t *testing.T) { + tests := []struct { + name string + slice []string + s string + want []string + }{ + {"Remove from empty slice", []string{}, "apple", []string{}}, + {"Remove non-existing element", []string{"banana", "orange"}, "apple", []string{"banana", "orange"}}, + {"Remove existing element", []string{"apple", "banana", "orange"}, "banana", []string{"apple", "orange"}}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := RemoveString(tt.slice, tt.s) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("RemoveString() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestContainsString(t *testing.T) { + tests := []struct { + name string + arr []string + s string + want bool + }{ + {"Empty slice", []string{}, "apple", false}, + {"Element not present", []string{"banana", "orange"}, "apple", false}, + {"Element present", []string{"apple", "banana", "orange"}, "banana", true}, + {"Element with spaces", []string{" apple ", "banana", "orange "}, "apple", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := ContainsString(tt.arr, tt.s) + if got != tt.want { + t.Errorf("ContainsString() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestEqual(t *testing.T) { + tests := []struct { + name string + a []string + b []string + want bool + }{ + {"Equal slices", []string{"apple", "banana", "orange"}, []string{"apple", "banana", "orange"}, true}, + {"Different order", []string{"apple", "banana", "orange"}, []string{"banana", "orange", "apple"}, true}, + {"Different elements", []string{"apple", "banana", "orange"}, []string{"apple", "grape", "orange"}, false}, + {"Different lengths", []string{"apple", "banana", "orange"}, []string{"apple", "banana"}, false}, + {"Empty slices", []string{}, []string{}, true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := Equal(tt.a, tt.b) + if got != tt.want { + t.Errorf("Equal() = %v, want %v", got, tt.want) + } + }) + } + + // Additional test for ensuring sorting doesn't affect the result + t.Run("Sorting doesn't affect equality", func(t *testing.T) { + a := []string{"apple", "banana", "orange"} + b := []string{"banana", "orange", "apple"} + Equal(a, b) + if !reflect.DeepEqual(a, []string{"apple", "banana", "orange"}) || + !reflect.DeepEqual(b, []string{"banana", "orange", "apple"}) { + t.Errorf("Sorting should not affect the input slices") + } + }) +} + +func TestGenerateRandomString(t *testing.T) { + tests := []struct { + name string + length int + }{ + {"Zero length", 0}, + {"Positive length", 10}, + {"Long length", 50}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GenerateRandomString(tt.length) + + if err != nil { + t.Errorf("GenerateRandomString() error = %v", err) + return + } + + decoded, err := base64.URLEncoding.DecodeString(got) + if err != nil { + t.Errorf("Error decoding base64 string: %v", err) + } + + // Check if the decoded string has the expected length + if len(decoded) != tt.length { + t.Errorf("GenerateRandomString() length = %v, want %v", len(decoded), tt.length) + } + }) + } +} diff --git a/pkg/util/time_test.go b/pkg/util/time_test.go new file mode 100644 index 000000000..45807cbc9 --- /dev/null +++ b/pkg/util/time_test.go @@ -0,0 +1,31 @@ +package util + +import ( + "testing" + "time" +) + +func TestNowBytes(t *testing.T) { + t.Run("Test NowBytes", func(t *testing.T) { + got := NowBytes() + nowStr := time.Now().UTC().Format(time.RFC3339) + expected := []byte(nowStr) + + if !bytesEqual(got, expected) { + t.Errorf("NowBytes() = %v, want %v", got, expected) + } + }) +} + +// Helper function to check equality of two byte slices +func bytesEqual(a, b []byte) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} diff --git a/pkg/workloads/configmap.go b/pkg/workloads/configmap.go index 322e6931a..6270a7373 100644 --- a/pkg/workloads/configmap.go +++ b/pkg/workloads/configmap.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type ConfigMapRequest struct { ObjectMeta metav1.ObjectMeta Data map[string]string + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newConfigMap returns a new ConfigMap instance for the given ArgoCD. @@ -38,7 +42,7 @@ func RequestConfigMap(request ConfigMapRequest) (*corev1.ConfigMap, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, configMap, request.Client) + err := mutation(request.Instance, configMap, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/deployment.go b/pkg/workloads/deployment.go index d4f1d2382..efb76e5e3 100644 --- a/pkg/workloads/deployment.go +++ b/pkg/workloads/deployment.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type DeploymentRequest struct { ObjectMeta metav1.ObjectMeta Spec appsv1.DeploymentSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newDeployment returns a new Deployment instance for the given ArgoCD. @@ -39,7 +43,7 @@ func RequestDeployment(request DeploymentRequest) (*appsv1.Deployment, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, deployment, request.Client) + err := mutation(request.Instance, deployment, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/hpa.go b/pkg/workloads/hpa.go index 43c52baec..cef858db4 100644 --- a/pkg/workloads/hpa.go +++ b/pkg/workloads/hpa.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,10 +17,13 @@ import ( type HorizontalPodAutoscalerRequest struct { ObjectMeta metav1.ObjectMeta Spec autoscaling.HorizontalPodAutoscalerSpec + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newHorizontalPodAutoscaler returns a new HorizontalPodAutoscaler instance for the given ArgoCD. @@ -39,7 +43,7 @@ func RequestHorizontalPodAutoscaler(request HorizontalPodAutoscalerRequest) (*au if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, horizontalPodAutoscaler, request.Client) + err := mutation(request.Instance, horizontalPodAutoscaler, request.Client, request.MutationArgs, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/secret.go b/pkg/workloads/secret.go index 2ca52c719..82e663b89 100644 --- a/pkg/workloads/secret.go +++ b/pkg/workloads/secret.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" @@ -18,10 +19,13 @@ type SecretRequest struct { Data map[string][]byte StringData map[string]string Type corev1.SecretType + Instance *argoproj.ArgoCD - // array of functions to mutate role before returning to requester + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newSecret returns a new Secret instance for the given ArgoCD. @@ -42,7 +46,7 @@ func RequestSecret(request SecretRequest) (*corev1.Secret, error) { if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, secret, request.Client) + err := mutation(request.Instance, secret, request.Client, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/statefulset.go b/pkg/workloads/statefulset.go index e1c389430..3cb0322f4 100644 --- a/pkg/workloads/statefulset.go +++ b/pkg/workloads/statefulset.go @@ -8,6 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/resource" ) @@ -16,9 +17,13 @@ import ( type StatefulSetRequest struct { ObjectMeta metav1.ObjectMeta Spec appsv1.StatefulSetSpec - // array of functions to mutate role before returning to requester + Instance *argoproj.ArgoCD + + // array of functions to mutate obj before returning to requester Mutations []mutation.MutateFunc - Client cntrlClient.Client + // array of arguments to pass to the mutation funcs + MutationArgs []interface{} + Client cntrlClient.Client } // newStateful returns a new Stateful instance for the given ArgoCD. @@ -38,7 +43,7 @@ func RequestStatefulSet(request StatefulSetRequest) (*appsv1.StatefulSet, error) if len(request.Mutations) > 0 { for _, mutation := range request.Mutations { - err := mutation(nil, StatefulSet, request.Client) + err := mutation(request.Instance, StatefulSet, request.Client, request.MutationArgs, request.MutationArgs) if err != nil { mutationErr = err } diff --git a/pkg/workloads/workloads_test.go b/pkg/workloads/workloads_test.go index fe9a50ed7..ff378ab8b 100644 --- a/pkg/workloads/workloads_test.go +++ b/pkg/workloads/workloads_test.go @@ -33,11 +33,11 @@ var ( } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } -func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client) error { +func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *appsv1.Deployment: obj.Name = testNameMutated From 6eac1ddad14fec0bab05bc2277a92f4622824fd0 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 18 Jan 2024 12:37:45 -0500 Subject: [PATCH 58/94] remove changes to argocd controller Signed-off-by: Jaideep Rao --- controllers/argocd/argocd_controller.go | 86 ++++++++++++++++++------- 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 446b79a97..476555542 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -39,8 +39,7 @@ import ( "github.com/argoproj-labs/argocd-operator/controllers/argocd/sso" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/monitoring" - "github.com/argoproj-labs/argocd-operator/pkg/networking" - "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/argoproj-labs/argocd-operator/pkg/openshift" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -54,7 +53,9 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" ctrlLog "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -214,11 +215,11 @@ func (r *ArgoCDReconciler) Reconcile(ctx context.Context, request ctrl.Request) // return reconcile.Result{}, nil // } - // if !r.Instance.IsDeletionFinalizerPresent() { - // if err := r.addDeletionFinalizer(r.Instance); err != nil { - // return reconcile.Result{}, err - // } - // } + if !r.Instance.IsDeletionFinalizerPresent() { + if err := r.addDeletionFinalizer(r.Instance); err != nil { + return reconcile.Result{}, err + } + } if err = r.setResourceManagedNamespaces(); err != nil { return reconcile.Result{}, err @@ -271,7 +272,7 @@ func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) ( // Match the value of labelSelector from ReconcileArgoCD to labels from the argocd instance if !labelSelector.Matches(labels.Set(argocd.Labels)) { reqLogger.Info(fmt.Sprintf("the ArgoCD instance '%s' does not match the label selector '%s' and skipping for reconciliation", request.NamespacedName, r.LabelSelector)) - return reconcile.Result{}, fmt.Errorf("error: failed to reconcile ArgoCD instance: '%s'", request.NamespacedName) + return reconcile.Result{}, fmt.Errorf("Error: failed to reconcile ArgoCD instance: '%s'", request.NamespacedName) } newPhase := argocd.Status.Phase @@ -467,7 +468,7 @@ func (r *ArgoCDReconciler) setAppManagedNamespaces() error { } // check if any of the exisiting namespaces are carrying the label when they should not be. If yes, remove it - for existingNs := range existingManagedNsMap { + for existingNs, _ := range existingManagedNsMap { if _, ok := desiredManagedNsMap[existingNs]; !ok { ns, err := cluster.GetNamespace(existingNs, r.Client) if err != nil { @@ -551,7 +552,8 @@ func (r *ArgoCDReconciler) reconcileControllers() error { } func (r *ArgoCDReconciler) InitializeControllerReconcilers() { - r.SecretController = &secret.SecretReconciler{ + + secretController := &secret.SecretReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, @@ -559,28 +561,25 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { ManagedNamespaces: r.ResourceManagedNamespaces, } - r.ConfigMapController = &configmap.ConfigMapReconciler{ + configMapController := &configmap.ConfigMapReconciler{ Client: &r.Client, Scheme: r.Scheme, Instance: r.Instance, } - r.RedisController = &redis.RedisReconciler{ + redisController := &redis.RedisReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, } - r.ReposerverController = &reposerver.RepoServerReconciler{ + reposerverController := &reposerver.RepoServerReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, - - AppController: r.AppController, - ServerController: r.ServerController, } - r.ServerController = &server.ServerReconciler{ + serverController := &server.ServerReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, @@ -589,13 +588,13 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { SourceNamespaces: r.AppManagedNamespaces, } - r.NotificationsController = ¬ifications.NotificationsReconciler{ + notificationsController := ¬ifications.NotificationsReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, } - r.AppController = &appcontroller.AppControllerReconciler{ + appController := &appcontroller.AppControllerReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, @@ -604,17 +603,36 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { SourceNamespaces: r.AppManagedNamespaces, } - r.AppsetController = &applicationset.ApplicationSetReconciler{ + appsetController := &applicationset.ApplicationSetReconciler{ Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, } - r.SSOController = &sso.SSOReconciler{ + ssoController := &sso.SSOReconciler{ Client: &r.Client, Scheme: r.Scheme, Instance: r.Instance, } + + r.AppController = appController + + r.ServerController = serverController + + r.ReposerverController = reposerverController + + r.AppsetController = appsetController + + r.RedisController = redisController + + r.NotificationsController = notificationsController + + r.SSOController = ssoController + + r.ConfigMapController = configMapController + + r.SecretController = secretController + } // SetupWithManager sets up the controller with the Manager. @@ -628,6 +646,7 @@ func (r *ReconcileArgoCD) SetupWithManager(mgr ctrl.Manager) error { func (r *ArgoCDReconciler) SetupWithManager(mgr ctrl.Manager) error { bldr := ctrl.NewControllerManagedBy(mgr) r.setResourceWatches(bldr) + bldr.WithEventFilter(ignoreDeletionPredicate()) return bldr.Complete(r) } @@ -658,7 +677,7 @@ func (r *ArgoCDReconciler) setResourceWatches(bldr *builder.Builder) *builder.Bu bldr.Owns(&v1.RoleBinding{}) - if networking.IsRouteAPIAvailable() { + if openshift.IsRouteAPIAvailable() { // Watch OpenShift Route sub-resources owned by ArgoCD instances. bldr.Owns(&routev1.Route{}) } @@ -671,10 +690,31 @@ func (r *ArgoCDReconciler) setResourceWatches(bldr *builder.Builder) *builder.Bu bldr.Owns(&monitoringv1.ServiceMonitor{}) } - if workloads.IsTemplateAPIAvailable() { + if openshift.IsTemplateAPIAvailable() { // Watch for the changes to Deployment Config bldr.Owns(&oappsv1.DeploymentConfig{}) } return bldr } + +func (r *ArgoCDReconciler) addDeletionFinalizer(argocd *argoproj.ArgoCD) error { + argocd.Finalizers = append(argocd.Finalizers, common.ArgoCDDeletionFinalizer) + if err := r.Client.Update(context.TODO(), argocd); err != nil { + return fmt.Errorf("failed to add deletion finalizer for %s: %w", argocd.Name, err) + } + return nil +} + +func ignoreDeletionPredicate() predicate.Predicate { + return predicate.Funcs{ + UpdateFunc: func(e event.UpdateEvent) bool { + // Ignore updates to CR status in which case metadata.Generation does not change + return e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration() + }, + DeleteFunc: func(e event.DeleteEvent) bool { + // Evaluates to false if the object has been confirmed deleted. + return !e.DeleteStateUnknown + }, + } +} From 2b43b6f03b9668f45fcc783967c30c84321ae524 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 18 Jan 2024 12:39:53 -0500 Subject: [PATCH 59/94] remove other changes Signed-off-by: Jaideep Rao --- controllers/argocd/appcontroller/appcontroller.go | 2 +- controllers/argocd/redis/redis.go | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/controllers/argocd/appcontroller/appcontroller.go b/controllers/argocd/appcontroller/appcontroller.go index 3dac91850..ccbd27ce9 100644 --- a/controllers/argocd/appcontroller/appcontroller.go +++ b/controllers/argocd/appcontroller/appcontroller.go @@ -9,7 +9,7 @@ import ( ) type AppControllerReconciler struct { - Client *client.Client + Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD ClusterScoped bool diff --git a/controllers/argocd/redis/redis.go b/controllers/argocd/redis/redis.go index e8f6fd271..7a5b4e58e 100644 --- a/controllers/argocd/redis/redis.go +++ b/controllers/argocd/redis/redis.go @@ -3,11 +3,9 @@ package redis import ( "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" ) type RedisReconciler struct { @@ -18,7 +16,6 @@ type RedisReconciler struct { } func (rr *RedisReconciler) Reconcile() error { - rr.Logger = ctrl.Log.WithName(common.RedisControllerComponent).WithValues("instance", rr.Instance.Name, "instance-namespace", rr.Instance.Namespace) // controller logic goes here return nil From 2cdb18dd683759d3a1e3e01fd93a7f342aebcd99 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 18 Jan 2024 12:41:00 -0500 Subject: [PATCH 60/94] remove util file Signed-off-by: Jaideep Rao --- controllers/argocd/appcontroller/util.go | 22 ---------------------- controllers/argocd/server/util.go | 19 ------------------- 2 files changed, 41 deletions(-) delete mode 100644 controllers/argocd/appcontroller/util.go delete mode 100644 controllers/argocd/server/util.go diff --git a/controllers/argocd/appcontroller/util.go b/controllers/argocd/appcontroller/util.go deleted file mode 100644 index 1a304e8fe..000000000 --- a/controllers/argocd/appcontroller/util.go +++ /dev/null @@ -1,22 +0,0 @@ -package appcontroller - -import ( - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/util" - "github.com/argoproj-labs/argocd-operator/pkg/workloads" -) - -func (acr *AppControllerReconciler) TriggerAppControllerStatefulSetRollout() error { - name := argoutil.NameWithSuffix(acr.Instance.Name, common.ApplicationControllerComponent) - return workloads.TriggerStatefulSetRollout(acr.Client, name, acr.Instance.Namespace, func(name string, namespace string) { - statefulSet, err := workloads.GetStatefulSet(name, namespace, acr.Client) - if err != nil { - acr.Logger.Error(err, "TriggerAppControllerStatefulSetRollout: failed to trigger server deployment", "name", name, "namespace", namespace) - } - if statefulSet.Spec.Template.ObjectMeta.Labels == nil { - statefulSet.Spec.Template.ObjectMeta.Labels = make(map[string]string) - } - statefulSet.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() - }) -} diff --git a/controllers/argocd/server/util.go b/controllers/argocd/server/util.go deleted file mode 100644 index bc0072164..000000000 --- a/controllers/argocd/server/util.go +++ /dev/null @@ -1,19 +0,0 @@ -package server - -import ( - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/util" - "github.com/argoproj-labs/argocd-operator/pkg/workloads" -) - -func (sr *ServerReconciler) TriggerServerDeploymentRollout() error { - name := argoutil.NameWithSuffix(sr.Instance.Name, common.ServerControllerComponent) - return workloads.TriggerDeploymentRollout(sr.Client, name, sr.Instance.Namespace, func(name string, namespace string) { - deployment, err := workloads.GetDeployment(name, namespace, sr.Client) - if err != nil { - sr.Logger.Error(err, "triggerServerDeploymentRollout: failed to trigger server deployment", "name", name, "namespace", namespace) - } - deployment.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() - }) -} From 170f5d900032761a35aceb8208cfa9f01d4a9c41 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 22 Jan 2024 16:56:34 -0500 Subject: [PATCH 61/94] wip polish repo-server Signed-off-by: Jaideep Rao --- common/TOBEREMOVED.go | 6 ++ common/reposerver.go | 18 +++- controllers/argocd/TOBEREMOVED.go | 91 ++++++++++++++++++ .../argocd/appcontroller/appcontroller.go | 5 + .../argocd/appcontroller/statefulset.go | 7 ++ controllers/argocd/argocd_controller.go | 3 + controllers/argocd/redis/helper.go | 36 +++++++ controllers/argocd/reposerver/deployment.go | 5 + controllers/argocd/reposerver/interfaces.go | 13 +++ controllers/argocd/reposerver/reposerver.go | 69 +++++++------- controllers/argocd/reposerver/secret.go | 95 ++++++++----------- controllers/argocd/reposerver/service.go | 47 ++++----- .../argocd/reposerver/serviceaccount.go | 47 +++++++++ controllers/argocd/reposerver/status.go | 40 ++++++++ controllers/argocd/secret.go | 68 ------------- controllers/argocd/server/deployment.go | 10 ++ controllers/argocd/server/server.go | 5 + controllers/argocd/status.go | 22 ----- 18 files changed, 376 insertions(+), 211 deletions(-) create mode 100644 controllers/argocd/appcontroller/statefulset.go create mode 100644 controllers/argocd/redis/helper.go create mode 100644 controllers/argocd/reposerver/interfaces.go create mode 100644 controllers/argocd/reposerver/serviceaccount.go create mode 100644 controllers/argocd/reposerver/status.go create mode 100644 controllers/argocd/server/deployment.go diff --git a/common/TOBEREMOVED.go b/common/TOBEREMOVED.go index c6ce3ab01..439507851 100644 --- a/common/TOBEREMOVED.go +++ b/common/TOBEREMOVED.go @@ -160,6 +160,12 @@ const ( // ArgoCDRedisHAImageEnvVar is the environment variable used to get the image // to used for the the Redis container in HA mode. ArgoCDRedisHAImageEnvVar = "ARGOCD_REDIS_HA_IMAGE" + + // ArgoCDDefaultRepoMetricsPort is the default listen port for the Argo CD repo server metrics. + ArgoCDDefaultRepoMetricsPort = 8084 + + // ArgoCDDefaultRepoServerPort is the default listen port for the Argo CD repo server. + ArgoCDDefaultRepoServerPort = 8081 ) // DefaultLabels returns the default set of labels for controllers. diff --git a/common/reposerver.go b/common/reposerver.go index 17575b899..c03fa70f7 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -2,6 +2,11 @@ package common // names const ( + RepoServerController = "repo-server-controller" + + // RepoServerComponent is the repo-server control plane component + RepoServerComponent = "repo-server" + // ArgoCDRepoServerTLSSecretName is the name of the TLS secret for the repo-server ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" @@ -16,9 +21,14 @@ const ( // defaults const ( - // ArgoCDDefaultRepoMetricsPort is the default listen port for the Argo CD repo server metrics. - ArgoCDDefaultRepoMetricsPort = 8084 + // DefaultRepoServerMetricsPort is the default listen port for the Argo CD repo server metrics. + DefaultRepoServerMetricsPort = 8084 - // ArgoCDDefaultRepoServerPort is the default listen port for the Argo CD repo server. - ArgoCDDefaultRepoServerPort = 8081 + // DefaultRepoServerPort is the default listen port for the Argo CD repo server. + DefaultRepoServerPort = 8081 +) + +// keys +const ( + RepoTLSCertChangedKey = "repo.tls.cert.changed" ) diff --git a/controllers/argocd/TOBEREMOVED.go b/controllers/argocd/TOBEREMOVED.go index d789f2337..36125d479 100644 --- a/controllers/argocd/TOBEREMOVED.go +++ b/controllers/argocd/TOBEREMOVED.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "crypto/rand" + "crypto/sha256" "encoding/base64" "errors" "fmt" @@ -2214,3 +2215,93 @@ func newRouteWithName(name string, cr *argoproj.ArgoCD) *routev1.Route { func newRouteWithSuffix(suffix string, cr *argoproj.ArgoCD) *routev1.Route { return newRouteWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), cr) } + +// reconcileStatusRepo will ensure that the Repo status is updated for the given ArgoCD. +func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoproj.ArgoCD) error { + status := "Unknown" + + deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, deploy.Name, deploy) { + status = "Pending" + + if deploy.Spec.Replicas != nil { + if deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { + status = "Running" + } + } + } + + if cr.Status.Repo != status { + cr.Status.Repo = status + return r.Client.Status().Update(context.TODO(), cr) + } + return nil +} + +// reconcileRepoServerTLSSecret checks whether the argocd-repo-server-tls secret +// has changed since our last reconciliation loop. It does so by comparing the +// checksum of tls.crt and tls.key in the status of the ArgoCD CR against the +// values calculated from the live state in the cluster. +func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoproj.ArgoCD) error { + var tlsSecretObj corev1.Secret + var sha256sum string + + log.Info("reconciling repo-server TLS secret") + + tlsSecretName := types.NamespacedName{Namespace: cr.Namespace, Name: common.ArgoCDRepoServerTLSSecretName} + err := r.Client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } else if tlsSecretObj.Type != corev1.SecretTypeTLS { + // We only process secrets of type kubernetes.io/tls + return nil + } else { + // We do the checksum over a concatenated byte stream of cert + key + crt, crtOk := tlsSecretObj.Data[corev1.TLSCertKey] + key, keyOk := tlsSecretObj.Data[corev1.TLSPrivateKeyKey] + if crtOk && keyOk { + var sumBytes []byte + sumBytes = append(sumBytes, crt...) + sumBytes = append(sumBytes, key...) + sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) + } + } + + // The content of the TLS secret has changed since we last looked if the + // calculated checksum doesn't match the one stored in the status. + if cr.Status.RepoTLSChecksum != sha256sum { + // We store the value early to prevent a possible restart loop, for the + // cost of a possibly missed restart when we cannot update the status + // field of the resource. + cr.Status.RepoTLSChecksum = sha256sum + err = r.Client.Status().Update(context.TODO(), cr) + if err != nil { + return err + } + + // Trigger rollout of API server + apiDepl := newDeploymentWithSuffix("server", "server", cr) + err = r.triggerRollout(apiDepl, "repo.tls.cert.changed") + if err != nil { + return err + } + + // Trigger rollout of repository server + repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", cr) + err = r.triggerRollout(repoDepl, "repo.tls.cert.changed") + if err != nil { + return err + } + + // Trigger rollout of application controller + controllerSts := newStatefulSetWithSuffix("application-controller", "application-controller", cr) + err = r.triggerRollout(controllerSts, "repo.tls.cert.changed") + if err != nil { + return err + } + } + + return nil +} diff --git a/controllers/argocd/appcontroller/appcontroller.go b/controllers/argocd/appcontroller/appcontroller.go index ccbd27ce9..4c98ebeca 100644 --- a/controllers/argocd/appcontroller/appcontroller.go +++ b/controllers/argocd/appcontroller/appcontroller.go @@ -23,3 +23,8 @@ func (acr *AppControllerReconciler) Reconcile() error { // controller logic goes here return nil } + +// TO DO: finish this +func (acr *AppControllerReconciler) TriggerRollout(key string) error { + return acr.TriggerStatefulSetRollout("", "", key) +} diff --git a/controllers/argocd/appcontroller/statefulset.go b/controllers/argocd/appcontroller/statefulset.go new file mode 100644 index 000000000..d56ad4e68 --- /dev/null +++ b/controllers/argocd/appcontroller/statefulset.go @@ -0,0 +1,7 @@ +package appcontroller + +import "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + +func (acr *AppControllerReconciler) TriggerStatefulSetRollout(name, namespace, key string) error { + return argocdcommon.TriggerStatefulSetRollout(name, namespace, key, acr.Client) +} diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 476555542..bd85267b1 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -620,6 +620,9 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { r.ServerController = serverController r.ReposerverController = reposerverController + r.ReposerverController.Appcontroller = appController + r.ReposerverController.Server = serverController + r.ReposerverController.Redis = redisController r.AppsetController = appsetController diff --git a/controllers/argocd/redis/helper.go b/controllers/argocd/redis/helper.go new file mode 100644 index 000000000..0650e0d77 --- /dev/null +++ b/controllers/argocd/redis/helper.go @@ -0,0 +1,36 @@ +package redis + +import ( + "reflect" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" +) + +// UseTLS decides whether Redis component should communicate with TLS or not +func (rr *RedisReconciler) UseTLS() bool { + tlsSecret, err := workloads.GetSecret(common.ArgoCDRedisServerTLSSecretName, rr.Instance.Namespace, rr.Client) + if err != nil { + if apierrors.IsNotFound(err) { + rr.Logger.V(1).Info("skipping TLS enforcement") + return false + } + rr.Logger.Error(err, "UseTLS: failed to retrieve tls secret", "name", common.ArgoCDRedisServerTLSSecretName, "namespace", rr.Instance.Namespace) + return false + } + + secretOwner, err := argocdcommon.FindSecretOwnerInstance(types.NamespacedName{Name: tlsSecret.Name, Namespace: tlsSecret.Namespace}, rr.Client) + if err != nil { + rr.Logger.Error(err, "UseTLS: failed to find secret owning instance") + return false + } + + if !reflect.DeepEqual(secretOwner, types.NamespacedName{}) { + return true + } + + return false +} diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index bbd36f7ef..38c3b7f97 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -395,3 +395,8 @@ func (rsr *RepoServerReconciler) getRepoServerPodVolumes() []corev1.Volume { } return volumes } + +// TriggerDeploymentRollout starts server deployment rollout by updating the given key +func (rsr *RepoServerReconciler) TriggerDeploymentRollout(name, namespace, key string) error { + return argocdcommon.TriggerDeploymentRollout(name, namespace, key, rsr.Client) +} diff --git a/controllers/argocd/reposerver/interfaces.go b/controllers/argocd/reposerver/interfaces.go new file mode 100644 index 000000000..2f90ee984 --- /dev/null +++ b/controllers/argocd/reposerver/interfaces.go @@ -0,0 +1,13 @@ +package reposerver + +type AppController interface { + TriggerRollout(string) error +} + +type ServerController interface { + TriggerRollout(string) error +} + +type RedisController interface { + UseTLS() bool +} diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index d7493e204..02dfcb18b 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -9,37 +9,29 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + "github.com/argoproj-labs/argocd-operator/pkg/util" ) -type AppController interface { - TriggerAppControllerStatefulSetRollout() error -} - -type Server interface { - TriggerServerDeploymentRollout() error -} - type RepoServerReconciler struct { Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD Logger logr.Logger - AppController AppController - ServerController Server + Appcontroller AppController + Server ServerController + Redis RedisController } var ( - resourceName string - resourceLabels map[string]string - useTLSForRedis bool + resourceName string + component string ) func (rsr *RepoServerReconciler) Reconcile() error { - rsr.Logger = ctrl.Log.WithName(common.RepoServerControllerComponent).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) - resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerControllerComponent) - resourceLabels = common.DefaultResourceLabels(resourceName, rsr.Instance.Name, common.RepoServerControllerComponent) - useTLSForRedis = rsr.Instance.Spec.Repo.WantsAutoTLS() + rsr.Logger = ctrl.Log.WithName(common.RepoServerController).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) + component = common.RepoServerComponent + resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, component) if err := rsr.reconcileService(); err != nil { rsr.Logger.Info("reconciling repo server service") @@ -72,28 +64,35 @@ func (rsr *RepoServerReconciler) Reconcile() error { } func (rsr *RepoServerReconciler) DeleteResources() error { + var deletionErr util.MultiError - var deletionError error = nil + // delete deployment + err := rsr.deleteDeployment(resourceName, rsr.Instance.Namespace) + deletionErr.Append(err) - if err := rsr.deleteDeployment(resourceName, rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "DeleteResources: failed to delete deployment") - deletionError = err - } + // delete service monitor + err = rsr.deleteServiceMonitor(resourceName, rsr.Instance.Namespace) + deletionErr.Append(err) - if err := rsr.deleteTLSSecret(rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "DeleteResources: failed to delete secret") - deletionError = err - } + // delete service + err = rsr.deleteService(resourceName, rsr.Instance.Namespace) + deletionErr.Append(err) - if err := rsr.deleteServiceMonitor(resourceName, rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "DeleteResources: failed to delete serviceMonitor") - deletionError = err - } + // delete serviceaccount + err = rsr.deleteServiceAccount(resourceName, rsr.Instance.Namespace) + deletionErr.Append(err) - if err := rsr.deleteService(resourceName, rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "DeleteResources: failed to delete service") - deletionError = err - } + // delete TLS secret + err = rsr.deleteSecret(common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Namespace) + deletionErr.Append(err) + + return deletionErr.ErrOrNil() +} - return deletionError +func (rsr *RepoServerReconciler) TriggerRollout(key string) error { + if err := rsr.TriggerDeploymentRollout(resourceName, rsr.Instance.Namespace, key); err != nil { + rsr.Logger.Error(err, "TriggerRollout: failed to rollout repo-server deployment") + return err + } + return nil } diff --git a/controllers/argocd/reposerver/secret.go b/controllers/argocd/reposerver/secret.go index 654298ed8..68ab56837 100644 --- a/controllers/argocd/reposerver/secret.go +++ b/controllers/argocd/reposerver/secret.go @@ -1,90 +1,73 @@ package reposerver import ( - "context" - "crypto/sha256" - "fmt" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/pkg/cluster" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/pkg/errors" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" ) +// reconcileRepoServerTLSSecret checks whether the argocd-repo-server-tls secret +// has changed since our last reconciliation loop. It does so by comparing the +// checksum of tls.crt and tls.key in the status of the ArgoCD CR against the +// values calculated from the live state in the cluster. func (rsr *RepoServerReconciler) reconcileTLSSecret() error { + var reconErrs util.MultiError var sha256sum string - rsr.Logger.Info("reconciling TLS secrets") - namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) + sha256sum, err := argocdcommon.TLSSecretChecksum(types.NamespacedName{Name: common.ArgoCDRepoServerTLSSecretName, Namespace: rsr.Instance.Namespace}, rsr.Client) if err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to retrieve namespace", "name", rsr.Instance.Namespace) - return err - } - if namespace.DeletionTimestamp != nil { - if err := rsr.deleteTLSSecret(rsr.Instance.Namespace); err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to delete secret", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) - } - return err + reconErrs.Append(errors.Wrapf(err, "reconcileTLSSecret: failed to calculate checksum for %s in namespace %s", common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Namespace)) + return reconErrs } - existingSecret, err := workloads.GetSecret(common.RepoServerTLSSecretName, rsr.Instance.Namespace, rsr.Client) - if err != nil { - if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) - return err - } - } else if existingSecret.Type != corev1.SecretTypeTLS { + if sha256sum == "" { + rsr.Logger.V(1).Info("reconcileTLSSecret: received empty checksum; secret of type other than kubernetes.io/tls encountered") return nil - } else { - crt, crtOk := existingSecret.Data[corev1.TLSCertKey] - key, keyOk := existingSecret.Data[corev1.TLSPrivateKeyKey] - if crtOk && keyOk { - var sumBytes []byte - sumBytes = append(sumBytes, crt...) - sumBytes = append(sumBytes, key...) - sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) - } } + // The content of the TLS secret has changed since we last looked if the + // calculated checksum doesn't match the one stored in the status. if rsr.Instance.Status.RepoTLSChecksum != sha256sum { + // We store the value early to prevent a possible restart loop, for the + // cost of a possibly missed restart when we cannot update the status + // field of the resource. rsr.Instance.Status.RepoTLSChecksum = sha256sum - err = rsr.Client.Status().Update(context.TODO(), rsr.Instance) - // err = workloads.UpdateSecret(desiredSecret, rsr.Client) + err = rsr.UpdateInstanceStatus() if err != nil { - rsr.Logger.Error(err, "reconcileSecret: failed to update status", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) - return err + reconErrs.Append(errors.Wrapf(err, "reconcileTLSSecret")) } - // Trigger rollout of API components - err = rsr.TriggerRepoServerDeploymentRollout() - if err != nil { - return err + // trigger server rollout + if err := rsr.Server.TriggerRollout(common.RepoTLSCertChangedKey); err != nil { + reconErrs.Append(errors.Wrapf(err, "reconcileTLSSecret")) } - err = rsr.ServerController.TriggerServerDeploymentRollout() - if err != nil { - return err + // trigger repo-server rollout + if err := rsr.TriggerRollout(common.RepoTLSCertChangedKey); err != nil { + reconErrs.Append(errors.Wrapf(err, "reconcileTLSSecret")) } - err = rsr.AppController.TriggerAppControllerStatefulSetRollout() - if err != nil { - return err + // trigger app-controller rollout + if err := rsr.Appcontroller.TriggerRollout(common.RepoTLSCertChangedKey); err != nil { + reconErrs.Append(errors.Wrapf(err, "reconcileTLSSecret")) } - - rsr.Logger.V(0).Info("reconcileSecret: argocd client status updated", "name", common.RepoServerTLSSecretName, "namespace", rsr.Instance.Namespace) - return nil } + return reconErrs.ErrOrNil() - return nil } -func (rsr *RepoServerReconciler) deleteTLSSecret(namespace string) error { - if err := workloads.DeleteSecret(common.RepoServerTLSSecretName, namespace, rsr.Client); err != nil { - rsr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", common.RepoServerTLSSecretName, "namespace", namespace) - return err +func (rr *RepoServerReconciler) deleteSecret(name, namespace string) error { + if err := workloads.DeleteSecret(name, namespace, rr.Client); err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return errors.Wrapf(err, "deleteSecret: failed to delete secret %s", name) } - rsr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", common.RepoServerTLSSecretName, "namespace", namespace) + rr.Logger.V(0).Info("secret deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index 9128b3f59..708639843 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -2,13 +2,13 @@ package reposerver import ( "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/networking" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -18,13 +18,26 @@ func (rsr *RepoServerReconciler) reconcileService() error { rsr.Logger.Info("reconciling service") serviceRequest := networking.ServiceRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: rsr.Instance.Namespace, - Labels: resourceLabels, - Annotations: rsr.Instance.Annotations, + ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "server", + Port: common.DefaultRepoServerPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.DefaultRepoServerPort), + }, + { + Name: common.ArgoCDMetrics, + Port: common.ArgoCDDefaultRepoMetricsPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.DefaultRepoServerMetricsPort), + }, + }, + Selector: map[string]string{ + common.AppK8sKeyName: resourceName, + }, }, - Spec: GetServiceSpec(), Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, Client: rsr.Client, } @@ -87,23 +100,5 @@ func (rsr *RepoServerReconciler) deleteService(name, namespace string) error { } func GetServiceSpec() corev1.ServiceSpec { - return corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: common.Server, - Port: common.ArgoCDDefaultRepoServerPort, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, - { - Name: common.ArgoCDMetrics, - Port: common.ArgoCDDefaultRepoMetricsPort, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoMetricsPort), - }, - }, - Selector: map[string]string{ - common.AppK8sKeyName: resourceName, - }, - } + return } diff --git a/controllers/argocd/reposerver/serviceaccount.go b/controllers/argocd/reposerver/serviceaccount.go new file mode 100644 index 000000000..d875a7e0f --- /dev/null +++ b/controllers/argocd/reposerver/serviceaccount.go @@ -0,0 +1,47 @@ +package reposerver + +import ( + "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + "github.com/argoproj-labs/argocd-operator/pkg/permissions" + "github.com/pkg/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func (rsr *RepoServerReconciler) reconcileServiceAccount() error { + + saReq := permissions.ServiceAccountRequest{ + ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), + } + + desiredSa := permissions.RequestServiceAccount(saReq) + + if err := controllerutil.SetControllerReference(rsr.Instance, desiredSa, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileServiceAccount: failed to set owner reference for serviceaccount") + } + + _, err := permissions.GetServiceAccount(desiredSa.Name, desiredSa.Namespace, rsr.Client) + if err != nil { + if !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "reconcileServiceAccount: failed to retrieve serviceaccount") + } + + if err = permissions.CreateServiceAccount(desiredSa, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileServiceAccount: failed to create serviceaccount") + } + rsr.Logger.V(0).Info("serviceaccount created", "name", desiredSa.Name, "namespace", desiredSa.Namespace) + return nil + } + return nil +} + +func (rsr *RepoServerReconciler) deleteServiceAccount(name, namespace string) error { + if err := permissions.DeleteServiceAccount(name, namespace, rsr.Client); err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return errors.Wrapf(err, "deleteServiceAccount: failed to delete service account %s", name) + } + rsr.Logger.V(0).Info("service account deleted", "name", name, "namespace", namespace) + return nil +} diff --git a/controllers/argocd/reposerver/status.go b/controllers/argocd/reposerver/status.go new file mode 100644 index 000000000..5cae2f750 --- /dev/null +++ b/controllers/argocd/reposerver/status.go @@ -0,0 +1,40 @@ +package reposerver + +import ( + "context" + + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/pkg/errors" +) + +// reconcileStatus will ensure that the Repo-server status is updated for the given ArgoCD instance +func (rsr *RepoServerReconciler) reconcileStatus() error { + status := common.ArgoCDStatusUnknown + + deploy, err := workloads.GetDeployment(resourceName, rsr.Instance.Namespace, rsr.Client) + if err != nil { + return errors.Wrapf(err, "failed to retrieve deployment %s", resourceName) + } + + status = common.ArgoCDStatusPending + + if deploy.Spec.Replicas != nil { + if deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { + status = common.ArgoCDStatusRunning + } + } + + if rsr.Instance.Status.Repo != status { + rsr.Instance.Status.Repo = status + } + + return rsr.UpdateInstanceStatus() +} + +func (rsr *RepoServerReconciler) UpdateInstanceStatus() error { + if err := rsr.Client.Status().Update(context.TODO(), rsr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil +} diff --git a/controllers/argocd/secret.go b/controllers/argocd/secret.go index d8a299f20..8612df752 100644 --- a/controllers/argocd/secret.go +++ b/controllers/argocd/secret.go @@ -460,74 +460,6 @@ func (r *ReconcileArgoCD) reconcileClusterPermissionsSecret(cr *argoproj.ArgoCD) return r.Client.Create(context.TODO(), secret) } -// reconcileRepoServerTLSSecret checks whether the argocd-repo-server-tls secret -// has changed since our last reconciliation loop. It does so by comparing the -// checksum of tls.crt and tls.key in the status of the ArgoCD CR against the -// values calculated from the live state in the cluster. -func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoproj.ArgoCD) error { - var tlsSecretObj corev1.Secret - var sha256sum string - - log.Info("reconciling repo-server TLS secret") - - tlsSecretName := types.NamespacedName{Namespace: cr.Namespace, Name: common.ArgoCDRepoServerTLSSecretName} - err := r.Client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) - if err != nil { - if !apierrors.IsNotFound(err) { - return err - } - } else if tlsSecretObj.Type != corev1.SecretTypeTLS { - // We only process secrets of type kubernetes.io/tls - return nil - } else { - // We do the checksum over a concatenated byte stream of cert + key - crt, crtOk := tlsSecretObj.Data[corev1.TLSCertKey] - key, keyOk := tlsSecretObj.Data[corev1.TLSPrivateKeyKey] - if crtOk && keyOk { - var sumBytes []byte - sumBytes = append(sumBytes, crt...) - sumBytes = append(sumBytes, key...) - sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) - } - } - - // The content of the TLS secret has changed since we last looked if the - // calculated checksum doesn't match the one stored in the status. - if cr.Status.RepoTLSChecksum != sha256sum { - // We store the value early to prevent a possible restart loop, for the - // cost of a possibly missed restart when we cannot update the status - // field of the resource. - cr.Status.RepoTLSChecksum = sha256sum - err = r.Client.Status().Update(context.TODO(), cr) - if err != nil { - return err - } - - // Trigger rollout of API server - apiDepl := newDeploymentWithSuffix("server", "server", cr) - err = r.triggerRollout(apiDepl, "repo.tls.cert.changed") - if err != nil { - return err - } - - // Trigger rollout of repository server - repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", cr) - err = r.triggerRollout(repoDepl, "repo.tls.cert.changed") - if err != nil { - return err - } - - // Trigger rollout of application controller - controllerSts := newStatefulSetWithSuffix("application-controller", "application-controller", cr) - err = r.triggerRollout(controllerSts, "repo.tls.cert.changed") - if err != nil { - return err - } - } - - return nil -} - // reconcileRedisTLSSecret checks whether the argocd-operator-redis-tls secret // has changed since our last reconciliation loop. It does so by comparing the // checksum of tls.crt and tls.key in the status of the ArgoCD CR against the diff --git a/controllers/argocd/server/deployment.go b/controllers/argocd/server/deployment.go new file mode 100644 index 000000000..7d3e12776 --- /dev/null +++ b/controllers/argocd/server/deployment.go @@ -0,0 +1,10 @@ +package server + +import ( + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" +) + +// TriggerDeploymentRollout starts server deployment rollout by updating the given key +func (sr *ServerReconciler) TriggerDeploymentRollout(name, namespace, key string) error { + return argocdcommon.TriggerDeploymentRollout(name, namespace, key, sr.Client) +} diff --git a/controllers/argocd/server/server.go b/controllers/argocd/server/server.go index a696a4e2a..1926beb79 100644 --- a/controllers/argocd/server/server.go +++ b/controllers/argocd/server/server.go @@ -23,3 +23,8 @@ func (sr *ServerReconciler) Reconcile() error { // controller logic goes here return nil } + +// TO DO: fix this +func (acr *ServerReconciler) TriggerRollout(key string) error { + return acr.TriggerDeploymentRollout("", "", key) +} diff --git a/controllers/argocd/status.go b/controllers/argocd/status.go index a288f8c81..edf7f9719 100644 --- a/controllers/argocd/status.go +++ b/controllers/argocd/status.go @@ -257,28 +257,6 @@ func (r *ReconcileArgoCD) reconcileStatusRedis(cr *argoproj.ArgoCD) error { return nil } -// reconcileStatusRepo will ensure that the Repo status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoproj.ArgoCD) error { - status := "Unknown" - - deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, deploy.Name, deploy) { - status = "Pending" - - if deploy.Spec.Replicas != nil { - if deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { - status = "Running" - } - } - } - - if cr.Status.Repo != status { - cr.Status.Repo = status - return r.Client.Status().Update(context.TODO(), cr) - } - return nil -} - // reconcileStatusServer will ensure that the Server status is updated for the given ArgoCD. func (r *ReconcileArgoCD) reconcileStatusServer(cr *argoproj.ArgoCD) error { status := "Unknown" From a1068db912b3fb7f3e62531e8b0e31562392a56e Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 22 Jan 2024 17:16:36 -0500 Subject: [PATCH 62/94] generalize tls annotation mutation for all components Signed-off-by: Jaideep Rao --- common/keys.go | 1 + pkg/openshift/mutation.go | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/common/keys.go b/common/keys.go index 2998bdc37..70bef5360 100644 --- a/common/keys.go +++ b/common/keys.go @@ -212,4 +212,5 @@ const ( // misc const ( TLSSecretNameKey = "tls-secret-name" + WantAutoTLSKey = "wantAutoTLS" ) diff --git a/pkg/openshift/mutation.go b/pkg/openshift/mutation.go index 20e812b59..dd2d13629 100644 --- a/pkg/openshift/mutation.go +++ b/pkg/openshift/mutation.go @@ -2,6 +2,7 @@ package openshift import ( "fmt" + "strconv" "golang.org/x/mod/semver" corev1 "k8s.io/api/core/v1" @@ -30,24 +31,31 @@ func AddAutoTLSAnnotationForOpenShift(cr *argoproj.ArgoCD, resource interface{}, } switch obj := resource.(type) { case *corev1.Service: - if cr == nil { - return nil - } - // return if autoTLS is not requested - if !cr.Spec.Redis.WantsAutoTLS() { - return nil - } if obj.Annotations == nil { obj.Annotations = make(map[string]string) } // Ensure that args carries only one argument, which is a map of type map[string]string - // containing the key "tls-secret-name". If this is the case, the associated value - // can be used within the service annotation + // containing the keys "wantAutoTLS" and "tls-secret-name". If this is the case, the associated value + // can be used within the service annotation if auto TLS is requested if len(args) == 1 { for _, arg := range args { argMap := arg.(map[string]string) + + if val, ok := argMap[common.WantAutoTLSKey]; !ok { + return nil + } else { + wantTLS, err := strconv.ParseBool(val) + if err != nil { + return errors.Wrapf(err, "AddAutoTLSAnnotationForOpenShift: failed to parse mutation args for resource") + } + + if !wantTLS { + return nil + } + } + if val, ok := argMap[common.TLSSecretNameKey]; ok { obj.Annotations[common.ServiceBetaOpenshiftKeyCertSecret] = val } From 8b8c8af706cea57f9b718be71b17cc541c719e83 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 22 Jan 2024 17:24:01 -0500 Subject: [PATCH 63/94] add comment Signed-off-by: Jaideep Rao --- pkg/openshift/mutation.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/openshift/mutation.go b/pkg/openshift/mutation.go index dd2d13629..072a26843 100644 --- a/pkg/openshift/mutation.go +++ b/pkg/openshift/mutation.go @@ -51,6 +51,7 @@ func AddAutoTLSAnnotationForOpenShift(cr *argoproj.ArgoCD, resource interface{}, return errors.Wrapf(err, "AddAutoTLSAnnotationForOpenShift: failed to parse mutation args for resource") } + // return if autoTLS is not requested if !wantTLS { return nil } From 1d4354d742608c3d9e6b2b2c7d513e0d809969dc Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 22 Jan 2024 19:17:05 -0500 Subject: [PATCH 64/94] retouch sm, svc, sa, status, secret Signed-off-by: Jaideep Rao --- common/TOBEREMOVED.go | 3 + common/keys.go | 3 - common/redis.go | 8 + common/reposerver.go | 12 +- common/values.go | 6 +- controllers/argocd/TOBEREMOVED.go | 180 ++++++++++++++++++ controllers/argocd/deployment.go | 58 ------ controllers/argocd/prometheus.go | 32 ---- controllers/argocd/redis/helper.go | 5 + controllers/argocd/reposerver/helper.go | 99 ++++++++++ controllers/argocd/reposerver/interfaces.go | 1 + controllers/argocd/reposerver/reposerver.go | 8 +- controllers/argocd/reposerver/secret_test.go | 2 +- controllers/argocd/reposerver/service.go | 82 ++++---- .../argocd/reposerver/servicemonitor.go | 71 ++++--- controllers/argocd/reposerver/util.go | 87 --------- controllers/argocd/service.go | 44 ----- controllers/argocd/util.go | 46 ----- 18 files changed, 393 insertions(+), 354 deletions(-) create mode 100644 controllers/argocd/reposerver/helper.go delete mode 100644 controllers/argocd/reposerver/util.go diff --git a/common/TOBEREMOVED.go b/common/TOBEREMOVED.go index 439507851..410ac60a9 100644 --- a/common/TOBEREMOVED.go +++ b/common/TOBEREMOVED.go @@ -166,6 +166,9 @@ const ( // ArgoCDDefaultRepoServerPort is the default listen port for the Argo CD repo server. ArgoCDDefaultRepoServerPort = 8081 + + // ArgoCDKeyRelease is the prometheus release key for labels. + ArgoCDKeyRelease = "release" ) // DefaultLabels returns the default set of labels for controllers. diff --git a/common/keys.go b/common/keys.go index 70bef5360..d93ab55ee 100644 --- a/common/keys.go +++ b/common/keys.go @@ -78,9 +78,6 @@ const ( // ArgoCDKeyRBACScopes is the configuration key for the Argo CD RBAC scopes. ArgoCDKeyRBACScopes = "scopes" - // ArgoCDKeyRelease is the prometheus release key for labels. - ArgoCDKeyRelease = "release" - // ArgoCDKeyResourceExclusions is the configuration key for resource exclusions. ArgoCDKeyResourceExclusions = "resource.exclusions" diff --git a/common/redis.go b/common/redis.go index b687da112..a7375db0a 100644 --- a/common/redis.go +++ b/common/redis.go @@ -89,3 +89,11 @@ const ( const ( RedisTLSCertChangedKey = "redis.tls.cert.changed" ) + +// commands +const ( + RedisCmd = "--redis" + RedisUseTLSCmd = "--redis-use-tls" + RedisInsecureSkipTLSVerifyCmd = "--redis-insecure-skip-tls-verify" + RedisCACertificate = "--redis-ca-certificate" +) diff --git a/common/reposerver.go b/common/reposerver.go index c03fa70f7..ae8a6fba1 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -9,8 +9,13 @@ const ( // ArgoCDRepoServerTLSSecretName is the name of the TLS secret for the repo-server ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" +) + +// suffixes +const ( + RepoServerSuffix = "repo-server" - RepoServerSuffix = "-repo-server" + RepoServerMetricsSuffix = "repo-server-metrics" ) // values @@ -32,3 +37,8 @@ const ( const ( RepoTLSCertChangedKey = "repo.tls.cert.changed" ) + +// commands +const ( + RepoServerCmd = "argocd-repo-server" +) diff --git a/common/values.go b/common/values.go index 5e3b002be..b33938d19 100644 --- a/common/values.go +++ b/common/values.go @@ -49,6 +49,8 @@ const ( ArgoCDStatusRunning = "Running" ArgoCDStatusAvailable = "Available" + + PrometheusOperator = "prometheus-operator" ) // general values @@ -88,5 +90,7 @@ const ( // Commnds const ( - LogLevel = "--loglevel" + LogLevelCmd = "--loglevel" + LogFormatCmd = "--logformat" + UidEntryPointSh = "uid_entrypoint.sh" ) diff --git a/controllers/argocd/TOBEREMOVED.go b/controllers/argocd/TOBEREMOVED.go index 36125d479..0da4a16d6 100644 --- a/controllers/argocd/TOBEREMOVED.go +++ b/controllers/argocd/TOBEREMOVED.go @@ -2305,3 +2305,183 @@ func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoproj.ArgoCD) erro return nil } + +// reconcileRepoService will ensure that the Service for the Argo CD repo server is present. +func (r *ReconcileArgoCD) reconcileRepoService(cr *argoproj.ArgoCD) error { + svc := newServiceWithSuffix("repo-server", "repo-server", cr) + + if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + if !cr.Spec.Repo.IsEnabled() { + return r.Client.Delete(context.TODO(), svc) + } + if ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) { + return r.Client.Update(context.TODO(), svc) + } + return nil // Service found, do nothing + } + + if !cr.Spec.Repo.IsEnabled() { + return nil + } + + ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) + + svc.Spec.Selector = map[string]string{ + common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), + } + + svc.Spec.Ports = []corev1.ServicePort{ + { + Name: "server", + Port: common.ArgoCDDefaultRepoServerPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, { + Name: "metrics", + Port: common.ArgoCDDefaultRepoMetricsPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoMetricsPort), + }, + } + + if err := controllerutil.SetControllerReference(cr, svc, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), svc) +} + +// getArgoRepoResources will return the ResourceRequirements for the Argo CD Repo server container. +func getArgoRepoResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { + resources := corev1.ResourceRequirements{} + + // Allow override of resource requirements from CR + if cr.Spec.Repo.Resources != nil { + resources = *cr.Spec.Repo.Resources + } + + return resources +} + +func isRepoServerTLSVerificationRequested(cr *argoproj.ArgoCD) bool { + return cr.Spec.Repo.VerifyTLS +} + +// getRepoServerContainerImage will return the container image for the Repo server. +// +// There are three possible options for configuring the image, and this is the +// order of preference. +// +// 1. from the Spec, the spec.repo field has an image and version to use for +// generating an image reference. +// 2. from the Environment, this looks for the `ARGOCD_REPOSERVER_IMAGE` field and uses +// that if the spec is not configured. +// 3. the default is configured in common.ArgoCDDefaultRepoServerVersion and +// common.ArgoCDDefaultRepoServerImage. +func getRepoServerContainerImage(cr *argoproj.ArgoCD) string { + defaultImg, defaultTag := false, false + img := cr.Spec.Repo.Image + if img == "" { + img = common.ArgoCDDefaultArgoImage + defaultImg = true + } + + tag := cr.Spec.Repo.Version + if tag == "" { + tag = common.ArgoCDDefaultArgoVersion + defaultTag = true + } + if e := os.Getenv(common.ArgoCDImageEnvName); e != "" && (defaultTag && defaultImg) { + return e + } + return argoutil.CombineImageTag(img, tag) +} + +// getRepoServerAddress will return the Argo CD repo server address. +func getRepoServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.Repo.Remote != nil && *cr.Spec.Repo.Remote != "" { + return *cr.Spec.Repo.Remote + } + return fqdnServiceRef("repo-server", common.ArgoCDDefaultRepoServerPort, cr) +} + +// getArgoCDRepoServerReplicas will return the size value for the argocd-repo-server replica count if it +// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or +// replicas value is < 0. +func getArgoCDRepoServerReplicas(cr *argoproj.ArgoCD) *int32 { + if cr.Spec.Repo.Replicas != nil && *cr.Spec.Repo.Replicas >= 0 { + return cr.Spec.Repo.Replicas + } + + return nil +} + +// getArgoRepoCommand will return the command for the ArgoCD Repo component. +func getArgoRepoCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { + cmd := make([]string, 0) + + cmd = append(cmd, "uid_entrypoint.sh") + cmd = append(cmd, "argocd-repo-server") + + if cr.Spec.Redis.IsEnabled() { + cmd = append(cmd, "--redis", getRedisServerAddress(cr)) + } else { + log.Info("Redis is Disabled. Skipping adding Redis configuration to Repo Server.") + } + if useTLSForRedis { + cmd = append(cmd, "--redis-use-tls") + if isRedisTLSVerificationDisabled(cr) { + cmd = append(cmd, "--redis-insecure-skip-tls-verify") + } else { + cmd = append(cmd, "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt") + } + } + + cmd = append(cmd, "--loglevel") + cmd = append(cmd, getLogLevel(cr.Spec.Repo.LogLevel)) + + cmd = append(cmd, "--logformat") + cmd = append(cmd, getLogFormat(cr.Spec.Repo.LogFormat)) + + // *** NOTE *** + // Do Not add any new default command line arguments below this. + extraArgs := cr.Spec.Repo.ExtraRepoCommandArgs + err := isMergable(extraArgs, cmd) + if err != nil { + return cmd + } + + cmd = append(cmd, extraArgs...) + return cmd +} + +// reconcileRepoServerServiceMonitor will ensure that the ServiceMonitor is present for the Repo Server metrics Service. +func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoproj.ArgoCD) error { + sm := newServiceMonitorWithSuffix("repo-server-metrics", cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { + if !cr.Spec.Prometheus.Enabled { + // ServiceMonitor exists but enabled flag has been set to false, delete the ServiceMonitor + return r.Client.Delete(context.TODO(), sm) + } + return nil // ServiceMonitor found, do nothing + } + + if !cr.Spec.Prometheus.Enabled { + return nil // Prometheus not enabled, do nothing. + } + + sm.Spec.Selector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), + }, + } + sm.Spec.Endpoints = []monitoringv1.Endpoint{ + { + Port: common.ArgoCDMetrics, + }, + } + + if err := controllerutil.SetControllerReference(cr, sm, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), sm) +} diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go index 9e805408c..eea4b821b 100644 --- a/controllers/argocd/deployment.go +++ b/controllers/argocd/deployment.go @@ -35,17 +35,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) -// getArgoCDRepoServerReplicas will return the size value for the argocd-repo-server replica count if it -// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or -// replicas value is < 0. -func getArgoCDRepoServerReplicas(cr *argoproj.ArgoCD) *int32 { - if cr.Spec.Repo.Replicas != nil && *cr.Spec.Repo.Replicas >= 0 { - return cr.Spec.Repo.Replicas - } - - return nil -} - // getArgoCDServerReplicas will return the size value for the argocd-server replica count if it // has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or // replicas value is < 0. If Autoscale is enabled, the value for replicas in the argocd CR will be ignored. @@ -224,45 +213,6 @@ func getArgoRedisArgs(useTLS bool) []string { return args } -// getArgoRepoCommand will return the command for the ArgoCD Repo component. -func getArgoRepoCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { - cmd := make([]string, 0) - - cmd = append(cmd, "uid_entrypoint.sh") - cmd = append(cmd, "argocd-repo-server") - - if cr.Spec.Redis.IsEnabled() { - cmd = append(cmd, "--redis", getRedisServerAddress(cr)) - } else { - log.Info("Redis is Disabled. Skipping adding Redis configuration to Repo Server.") - } - if useTLSForRedis { - cmd = append(cmd, "--redis-use-tls") - if isRedisTLSVerificationDisabled(cr) { - cmd = append(cmd, "--redis-insecure-skip-tls-verify") - } else { - cmd = append(cmd, "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt") - } - } - - cmd = append(cmd, "--loglevel") - cmd = append(cmd, getLogLevel(cr.Spec.Repo.LogLevel)) - - cmd = append(cmd, "--logformat") - cmd = append(cmd, getLogFormat(cr.Spec.Repo.LogFormat)) - - // *** NOTE *** - // Do Not add any new default command line arguments below this. - extraArgs := cr.Spec.Repo.ExtraRepoCommandArgs - err := isMergable(extraArgs, cmd) - if err != nil { - return cmd - } - - cmd = append(cmd, extraArgs...) - return cmd -} - // getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container func getArgoCmpServerInitCommand() []string { cmd := make([]string, 0) @@ -337,14 +287,6 @@ func getDexServerAddress(cr *argoproj.ArgoCD) string { return fmt.Sprintf("https://%s", fqdnServiceRef("dex-server", common.ArgoCDDefaultDexHTTPPort, cr)) } -// getRepoServerAddress will return the Argo CD repo server address. -func getRepoServerAddress(cr *argoproj.ArgoCD) string { - if cr.Spec.Repo.Remote != nil && *cr.Spec.Repo.Remote != "" { - return *cr.Spec.Repo.Remote - } - return fqdnServiceRef("repo-server", common.ArgoCDDefaultRepoServerPort, cr) -} - // newDeployment returns a new Deployment instance for the given ArgoCD. func newDeployment(cr *argoproj.ArgoCD) *appsv1.Deployment { return &appsv1.Deployment{ diff --git a/controllers/argocd/prometheus.go b/controllers/argocd/prometheus.go index 2d8ccdb50..28c0fd05c 100644 --- a/controllers/argocd/prometheus.go +++ b/controllers/argocd/prometheus.go @@ -169,38 +169,6 @@ func (r *ReconcileArgoCD) reconcilePrometheus(cr *argoproj.ArgoCD) error { return r.Client.Create(context.TODO(), prometheus) } -// reconcileRepoServerServiceMonitor will ensure that the ServiceMonitor is present for the Repo Server metrics Service. -func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoproj.ArgoCD) error { - sm := newServiceMonitorWithSuffix("repo-server-metrics", cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { - if !cr.Spec.Prometheus.Enabled { - // ServiceMonitor exists but enabled flag has been set to false, delete the ServiceMonitor - return r.Client.Delete(context.TODO(), sm) - } - return nil // ServiceMonitor found, do nothing - } - - if !cr.Spec.Prometheus.Enabled { - return nil // Prometheus not enabled, do nothing. - } - - sm.Spec.Selector = metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), - }, - } - sm.Spec.Endpoints = []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, - } - - if err := controllerutil.SetControllerReference(cr, sm, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), sm) -} - // reconcileServerMetricsServiceMonitor will ensure that the ServiceMonitor is present for the ArgoCD Server metrics Service. func (r *ReconcileArgoCD) reconcileServerMetricsServiceMonitor(cr *argoproj.ArgoCD) error { sm := newServiceMonitorWithSuffix("server-metrics", cr) diff --git a/controllers/argocd/redis/helper.go b/controllers/argocd/redis/helper.go index 0650e0d77..ba3aff5c2 100644 --- a/controllers/argocd/redis/helper.go +++ b/controllers/argocd/redis/helper.go @@ -34,3 +34,8 @@ func (rr *RedisReconciler) UseTLS() bool { return false } + +// GetServerAddress will return the Redis service address for the given ArgoCD instance +func (rr *RedisReconciler) GetServerAddress() string { + return "" +} diff --git a/controllers/argocd/reposerver/helper.go b/controllers/argocd/reposerver/helper.go new file mode 100644 index 000000000..5fffe7069 --- /dev/null +++ b/controllers/argocd/reposerver/helper.go @@ -0,0 +1,99 @@ +package reposerver + +import ( + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + + "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + corev1 "k8s.io/api/core/v1" +) + +const ( + redisTLSCertPath = "/app/config/reposerver/tls/redis/tls.crt" +) + +func (rsr *RepoServerReconciler) TLSVerificationRequested() bool { + return rsr.Instance.Spec.Repo.VerifyTLS +} + +// getResources will return the ResourceRequirements for the Repo server container. +func (rsr *RepoServerReconciler) getResources() corev1.ResourceRequirements { + resources := corev1.ResourceRequirements{} + + // Allow override of resource requirements from CR + if rsr.Instance.Spec.Repo.Resources != nil { + resources = *rsr.Instance.Spec.Repo.Resources + } + + return resources +} + +// getContainerImage will return the container image for the repo-server. +func (rsr *RepoServerReconciler) getContainerImage() string { + fn := func(cr *argoproj.ArgoCD) (string, string) { + return cr.Spec.Repo.Image, cr.Spec.Repo.Version + } + return argocdcommon.GetContainerImage(fn, rsr.Instance, common.ArgoCDImageEnvVar, common.ArgoCDDefaultArgoImage, common.ArgoCDDefaultArgoVersion) +} + +// GetServerAddress will return the repo-server service address for the given ArgoCD instance +func (rsr *RepoServerReconciler) GetServerAddress() string { + if rsr.Instance.Spec.Redis.Remote != nil && *rsr.Instance.Spec.Redis.Remote != "" { + return *rsr.Instance.Spec.Redis.Remote + } + + return argoutil.FqdnServiceRef(resourceName, rsr.Instance.Namespace, common.DefaultRedisPort) +} + +// getReplicas will return the size value for the argocd-repo-server replica count if it +// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or +// replicas value is < 0. +func (rsr *RepoServerReconciler) getReplicas() *int32 { + if rsr.Instance.Spec.Repo.Replicas != nil && *rsr.Instance.Spec.Repo.Replicas >= 0 { + return rsr.Instance.Spec.Repo.Replicas + } + + return nil +} + +// getArgs will return the args for the repo server container +func (rsr *RepoServerReconciler) getArgs() []string { + cmd := make([]string, 0) + + cmd = append(cmd, common.UidEntryPointSh) + cmd = append(cmd, common.RepoServerCmd) + + if rsr.Instance.Spec.Redis.IsEnabled() { + cmd = append(cmd, common.RedisCmd, rsr.Redis.GetServerAddress()) + } + + // TO DO: make this a WARN instead + rsr.Logger.Info("redis is disabled, skipping redis configuration") + + if rsr.Redis.UseTLS() { + cmd = append(cmd, common.RedisUseTLSCmd) + if rsr.Instance.Spec.Redis.DisableTLSVerification { + cmd = append(cmd, common.RedisInsecureSkipTLSVerifyCmd) + } else { + cmd = append(cmd, common.RedisCACertificate, redisTLSCertPath) + } + } + + cmd = append(cmd, common.LogLevelCmd) + cmd = append(cmd, argoutil.GetLogLevel(rsr.Instance.Spec.Repo.LogLevel)) + + cmd = append(cmd, common.LogFormatCmd) + cmd = append(cmd, argoutil.GetLogFormat(rsr.Instance.Spec.Repo.LogFormat)) + + // *** NOTE *** + // Do Not add any new default command line arguments below this. + extraArgs := rsr.Instance.Spec.Repo.ExtraRepoCommandArgs + err := argocdcommon.IsMergable(extraArgs, cmd) + if err != nil { + return cmd + } + + cmd = append(cmd, extraArgs...) + return cmd +} diff --git a/controllers/argocd/reposerver/interfaces.go b/controllers/argocd/reposerver/interfaces.go index 2f90ee984..cb249756e 100644 --- a/controllers/argocd/reposerver/interfaces.go +++ b/controllers/argocd/reposerver/interfaces.go @@ -10,4 +10,5 @@ type ServerController interface { type RedisController interface { UseTLS() bool + GetServerAddress() string } diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 02dfcb18b..5bf73c553 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -24,14 +24,16 @@ type RepoServerReconciler struct { } var ( - resourceName string - component string + resourceName string + resourceMetricsName string + component string ) func (rsr *RepoServerReconciler) Reconcile() error { rsr.Logger = ctrl.Log.WithName(common.RepoServerController).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) component = common.RepoServerComponent - resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, component) + resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerSuffix) + resourceMetricsName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetricsSuffix) if err := rsr.reconcileService(); err != nil { rsr.Logger.Info("reconciling repo server service") diff --git a/controllers/argocd/reposerver/secret_test.go b/controllers/argocd/reposerver/secret_test.go index eafe55392..6dd09e9f5 100644 --- a/controllers/argocd/reposerver/secret_test.go +++ b/controllers/argocd/reposerver/secret_test.go @@ -25,7 +25,7 @@ func TestRepoServerReconciler_DeleteSecret(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { nr := tt.setupClient() - if err := nr.deleteTLSSecret(ns.Name); (err != nil) != tt.wantErr { + if err := nr.deleteSecret(ns.Name); (err != nil) != tt.wantErr { if tt.wantErr { t.Errorf("Expected error but did not get one") } else { diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index 708639843..a2c7dfefa 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -1,14 +1,18 @@ package reposerver import ( + "strconv" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/networking" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -17,7 +21,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { rsr.Logger.Info("reconciling service") - serviceRequest := networking.ServiceRequest{ + svcRequest := networking.ServiceRequest{ ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ @@ -29,7 +33,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { }, { Name: common.ArgoCDMetrics, - Port: common.ArgoCDDefaultRepoMetricsPort, + Port: common.DefaultRepoServerMetricsPort, Protocol: corev1.ProtocolTCP, TargetPort: intstr.FromInt(common.DefaultRepoServerMetricsPort), }, @@ -38,55 +42,59 @@ func (rsr *RepoServerReconciler) reconcileService() error { common.AppK8sKeyName: resourceName, }, }, + Instance: rsr.Instance, Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, - Client: rsr.Client, + MutationArgs: util.ConvertStringMapToInterfaces(map[string]string{ + common.TLSSecretNameKey: common.ArgoCDRepoServerTLSSecretName, + common.WantAutoTLSKey: strconv.FormatBool(rsr.Instance.Spec.Repo.WantsAutoTLS()), + }), + Client: rsr.Client, } - desiredService, err := networking.RequestService(serviceRequest) + desiredSvc, err := networking.RequestService(svcRequest) if err != nil { - rsr.Logger.Error(err, "reconcileService: failed to request service", "name", desiredService.Name, "namespace", desiredService.Namespace) - return err + return errors.Wrapf(err, "reconcileService: failed to request service %s", desiredSvc.Name) } - namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) - if err != nil { - rsr.Logger.Error(err, "reconcileService: failed to retrieve namespace", "name", rsr.Instance.Namespace) - return err - } - if namespace.DeletionTimestamp != nil { - if err := rsr.deleteService(desiredService.Name, desiredService.Namespace); err != nil { - rsr.Logger.Error(err, "reconcileService: failed to delete service", "name", desiredService.Name, "namespace", desiredService.Namespace) - } - return err + if err = controllerutil.SetControllerReference(rsr.Instance, desiredSvc, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desiredSvc.Name) } - existingService, err := networking.GetService(desiredService.Name, desiredService.Namespace, rsr.Client) + existingSvc, err := networking.GetService(desiredSvc.Name, desiredSvc.Namespace, rsr.Client) if err != nil { - if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileService: failed to retrieve service", "name", desiredService.Name, "namespace", desiredService.Namespace) - return err + if !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "reconcileService: failed to retrieve service %s", desiredSvc.Name) } - if err = controllerutil.SetControllerReference(rsr.Instance, desiredService, rsr.Scheme); err != nil { - rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desiredService.Name, "namespace", desiredService.Namespace) + if err = networking.CreateService(desiredSvc, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileService: failed to create service %s", desiredSvc.Name) } + rsr.Logger.V(0).Info("service created", "name", desiredSvc.Name, "namespace", desiredSvc.Namespace) + return nil + } - if err = networking.CreateService(desiredService, rsr.Client); err != nil { - rsr.Logger.Error(err, "reconcileService: failed to create service", "name", desiredService.Name, "namespace", desiredService.Namespace) - return err - } - rsr.Logger.V(0).Info("reconcileService: service created", "name", desiredService.Name, "namespace", desiredService.Namespace) + svcChanged := false + + fieldsToCompare := []struct { + existing, desired interface{} + extraAction func() + }{ + {&existingSvc.Annotations, &desiredSvc.Annotations, nil}, + } + + for _, field := range fieldsToCompare { + argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &svcChanged) + } + + if !svcChanged { return nil } - if networking.EnsureAutoTLSAnnotation(existingService, common.ArgoCDRepoServerTLSSecretName, useTLSForRedis, rsr.Logger) { - if err = networking.UpdateService(existingService, rsr.Client); err != nil { - rsr.Logger.Error(err, "reconcileService: failed to update service", "name", existingService.Name, "namespace", existingService.Namespace) - return err - } + if err = networking.UpdateService(existingSvc, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileService: failed to update service %s", existingSvc.Name) } - rsr.Logger.V(0).Info("reconcileService: service updated", "name", existingService.Name, "namespace", existingService.Namespace) + rsr.Logger.V(0).Info("service updated", "name", existingSvc.Name, "namespace", existingSvc.Namespace) return nil } @@ -98,7 +106,3 @@ func (rsr *RepoServerReconciler) deleteService(name, namespace string) error { rsr.Logger.V(0).Info("DeleteService: service deleted", "name", name, "namespace", namespace) return nil } - -func GetServiceSpec() corev1.ServiceSpec { - return -} diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index c1410b590..3fb9ce882 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -3,30 +3,29 @@ package reposerver import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/monitoring" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/pkg/errors" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { - rsr.Logger.Info("reconciling serviceMonitor") + // return if prometheus API is not present on cluster + if !monitoring.IsPrometheusAPIAvailable() { + rsr.Logger.V(1).Info("prometheus API unavailable, skip reconciling service monitor") + return nil + } - serviceMonitorRequest := monitoring.ServiceMonitorRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetrics), - Namespace: rsr.Instance.Namespace, - Labels: resourceLabels, - Annotations: rsr.Instance.Annotations, - }, + smReq := monitoring.ServiceMonitorRequest{ + ObjectMeta: argoutil.GetObjMeta(resourceMetricsName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ MatchLabels: map[string]string{ - common.AppK8sKeyName: argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerControllerComponent), + common.AppK8sKeyName: resourceName, }, }, Endpoints: []monitoringv1.Endpoint{ @@ -37,40 +36,27 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { }, } - desiredServiceMonitor, err := monitoring.RequestServiceMonitor(serviceMonitorRequest) - if err != nil { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to request serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) - return err - } + smReq.ObjectMeta.Labels[common.PrometheusReleaseKey] = common.PrometheusOperator - namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) + desiredSM, err := monitoring.RequestServiceMonitor(smReq) if err != nil { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to retrieve namespace", "name", rsr.Instance.Namespace) - return err + return errors.Wrapf(err, "reconcileServiceMonitor: failed to request service monitor %s", desiredSM.Name) } - if namespace.DeletionTimestamp != nil { - if err := rsr.deleteServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace); err != nil { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to delete serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) - } - return err + + if err = controllerutil.SetControllerReference(rsr.Instance, desiredSM, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to set owner reference for service monitor", "name", desiredSM.Name) } - _, err = monitoring.GetServiceMonitor(desiredServiceMonitor.Name, desiredServiceMonitor.Namespace, rsr.Client) + _, err = monitoring.GetServiceMonitor(desiredSM.Name, desiredSM.Namespace, rsr.Client) if err != nil { - if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to retrieve serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) - return err + if !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "reconcileServiceMonitor: failed to retrieve service %s", desiredSM.Name) } - if err = controllerutil.SetControllerReference(rsr.Instance, desiredServiceMonitor, rsr.Scheme); err != nil { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to set owner reference for serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + if err = monitoring.CreateServiceMonitor(desiredSM, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileServiceMonitor: failed to create service monitor %s", desiredSM.Name) } - - if err = monitoring.CreateServiceMonitor(desiredServiceMonitor, rsr.Client); err != nil { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to create serviceMonitor", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) - return err - } - rsr.Logger.V(0).Info("reconcileServiceMonitor: serviceMonitor created", "name", desiredServiceMonitor.Name, "namespace", desiredServiceMonitor.Namespace) + rsr.Logger.V(0).Info("service monitor created", "name", desiredSM.Name, "namespace", desiredSM.Namespace) return nil } @@ -78,10 +64,17 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { } func (rsr *RepoServerReconciler) deleteServiceMonitor(name, namespace string) error { + // return if prometheus API is not present on cluster + if !monitoring.IsPrometheusAPIAvailable() { + return nil + } + if err := monitoring.DeleteServiceMonitor(name, namespace, rsr.Client); err != nil { - rsr.Logger.Error(err, "DeleteServiceMonitor: failed to delete serviceMonitor", "name", name, "namespace", namespace) - return err + if apierrors.IsNotFound(err) { + return nil + } + return errors.Wrapf(err, "deleteServiceMonitor: failed to delete service %s", name) } - rsr.Logger.V(0).Info("DeleteServiceMonitor: serviceMonitor deleted", "name", name, "namespace", namespace) + rsr.Logger.V(0).Info("service monitor deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/util.go b/controllers/argocd/reposerver/util.go deleted file mode 100644 index 1ac17dadb..000000000 --- a/controllers/argocd/reposerver/util.go +++ /dev/null @@ -1,87 +0,0 @@ -package reposerver - -import ( - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - - "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/util" - "github.com/argoproj-labs/argocd-operator/pkg/workloads" - corev1 "k8s.io/api/core/v1" -) - -// GetRepoServerResources will return the ResourceRequirements for the Argo CD Repo server container. -func (rsr *RepoServerReconciler) GetRepoServerResources() corev1.ResourceRequirements { - resources := corev1.ResourceRequirements{} - - // Allow override of resource requirements from CR - if rsr.Instance.Spec.Repo.Resources != nil { - resources = *rsr.Instance.Spec.Repo.Resources - } - - return resources -} - -// GetRepoServerCommand will return the command for the ArgoCD Repo component. -func (rsr *RepoServerReconciler) GetRepoServerCommand(useTLSForRedis bool) []string { - cmd := make([]string, 0) - - cmd = append(cmd, common.UidEntryPointSh) - cmd = append(cmd, common.RepoServerController) - - cmd = append(cmd, common.Redis) - cmd = append(cmd, argocdcommon.GetRedisServerAddress(rsr.Instance)) - - if useTLSForRedis { - cmd = append(cmd, common.RedisUseTLS) - if rsr.Instance.Spec.Redis.DisableTLSVerification { - cmd = append(cmd, common.RedisInsecureSkipTLSVerify) - } else { - cmd = append(cmd, common.RedisCACertificate, common.RepoServerTLSRedisCertPath) - } - } - - cmd = append(cmd, common.LogLevel) - cmd = append(cmd, argoutil.GetLogLevel(rsr.Instance.Spec.Repo.LogLevel)) - - cmd = append(cmd, common.LogFormat) - cmd = append(cmd, argoutil.GetLogFormat(rsr.Instance.Spec.Repo.LogFormat)) - - // *** NOTE *** - // Do Not add any new default command line arguments below this. - extraArgs := rsr.Instance.Spec.Repo.ExtraRepoCommandArgs - err := argocdcommon.IsMergable(extraArgs, cmd) - if err != nil { - return cmd - } - - cmd = append(cmd, extraArgs...) - return cmd -} - -func (rsr *RepoServerReconciler) GetRepoServerReplicas() *int32 { - if rsr.Instance.Spec.Repo.Replicas != nil && *rsr.Instance.Spec.Repo.Replicas >= 0 { - return rsr.Instance.Spec.Repo.Replicas - } - - return nil -} - -// GetRepoServerAddress will return the Argo CD repo server address. -func GetRepoServerAddress(name string, namespace string) string { - return argoutil.FqdnServiceRef(argoutil.NameWithSuffix(name, common.RepoServerControllerComponent), namespace, common.ArgoCDDefaultRepoServerPort) -} - -func (rsr *RepoServerReconciler) TriggerRepoServerDeploymentRollout() error { - name := argoutil.NameWithSuffix(rsr.Instance.Name, common.RepoServerControllerComponent) - return workloads.TriggerDeploymentRollout(rsr.Client, name, rsr.Instance.Namespace, func(name string, namespace string) { - deployment, err := workloads.GetDeployment(name, namespace, rsr.Client) - if err != nil { - rsr.Logger.Error(err, "triggerRepoServerDeploymentRollout: failed to trigger repo-server deployment", "name", name, "namespace", namespace) - } - if deployment.Spec.Template.ObjectMeta.Labels == nil { - deployment.Spec.Template.ObjectMeta.Labels = make(map[string]string) - } - deployment.Spec.Template.ObjectMeta.Labels[common.ArgoCDRepoTLSCertChangedKey] = util.NowNano() - }) -} diff --git a/controllers/argocd/service.go b/controllers/argocd/service.go index b0f5ed7d7..150cd0cb1 100644 --- a/controllers/argocd/service.go +++ b/controllers/argocd/service.go @@ -356,50 +356,6 @@ func ensureAutoTLSAnnotation(svc *corev1.Service, secretName string, enabled boo return false } -// reconcileRepoService will ensure that the Service for the Argo CD repo server is present. -func (r *ReconcileArgoCD) reconcileRepoService(cr *argoproj.ArgoCD) error { - svc := newServiceWithSuffix("repo-server", "repo-server", cr) - - if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - if !cr.Spec.Repo.IsEnabled() { - return r.Client.Delete(context.TODO(), svc) - } - if ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) { - return r.Client.Update(context.TODO(), svc) - } - return nil // Service found, do nothing - } - - if !cr.Spec.Repo.IsEnabled() { - return nil - } - - ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) - - svc.Spec.Selector = map[string]string{ - common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), - } - - svc.Spec.Ports = []corev1.ServicePort{ - { - Name: "server", - Port: common.ArgoCDDefaultRepoServerPort, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, { - Name: "metrics", - Port: common.ArgoCDDefaultRepoMetricsPort, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoMetricsPort), - }, - } - - if err := controllerutil.SetControllerReference(cr, svc, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), svc) -} - // reconcileServerMetricsService will ensure that the Service for the Argo CD server metrics is present. func (r *ReconcileArgoCD) reconcileServerMetricsService(cr *argoproj.ArgoCD) error { svc := newServiceWithSuffix("server-metrics", "server", cr) diff --git a/controllers/argocd/util.go b/controllers/argocd/util.go index 8357d6e7b..71bae64f9 100644 --- a/controllers/argocd/util.go +++ b/controllers/argocd/util.go @@ -105,57 +105,11 @@ func getArgoApplicationControllerCommand(cr *argoproj.ArgoCD, useTLSForRedis boo return cmd } -// getRepoServerContainerImage will return the container image for the Repo server. -// -// There are three possible options for configuring the image, and this is the -// order of preference. -// -// 1. from the Spec, the spec.repo field has an image and version to use for -// generating an image reference. -// 2. from the Environment, this looks for the `ARGOCD_REPOSERVER_IMAGE` field and uses -// that if the spec is not configured. -// 3. the default is configured in common.ArgoCDDefaultRepoServerVersion and -// common.ArgoCDDefaultRepoServerImage. -func getRepoServerContainerImage(cr *argoproj.ArgoCD) string { - defaultImg, defaultTag := false, false - img := cr.Spec.Repo.Image - if img == "" { - img = common.ArgoCDDefaultArgoImage - defaultImg = true - } - - tag := cr.Spec.Repo.Version - if tag == "" { - tag = common.ArgoCDDefaultArgoVersion - defaultTag = true - } - if e := os.Getenv(common.ArgoCDImageEnvName); e != "" && (defaultTag && defaultImg) { - return e - } - return argoutil.CombineImageTag(img, tag) -} - -// getArgoRepoResources will return the ResourceRequirements for the Argo CD Repo server container. -func getArgoRepoResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { - resources := corev1.ResourceRequirements{} - - // Allow override of resource requirements from CR - if cr.Spec.Repo.Resources != nil { - resources = *cr.Spec.Repo.Resources - } - - return resources -} - // getArgoServerInsecure returns the insecure value for the ArgoCD Server component. func getArgoServerInsecure(cr *argoproj.ArgoCD) bool { return cr.Spec.Server.Insecure } -func isRepoServerTLSVerificationRequested(cr *argoproj.ArgoCD) bool { - return cr.Spec.Repo.VerifyTLS -} - func isRedisTLSVerificationDisabled(cr *argoproj.ArgoCD) bool { return cr.Spec.Redis.DisableTLSVerification } From 402843d2e890f09fada5fb609c0c5782571e9c21 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 22 Jan 2024 19:20:45 -0500 Subject: [PATCH 65/94] add prometheus const Signed-off-by: Jaideep Rao --- common/prometheus.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/prometheus.go b/common/prometheus.go index d012a5538..1098598e7 100644 --- a/common/prometheus.go +++ b/common/prometheus.go @@ -4,6 +4,9 @@ package common const ( // ArgoCDKeyPrometheus is the resource prometheus key for labels. ArgoCDKeyPrometheus = "prometheus" + + // PrometheusReleaseKey is the prometheus release key for labels. + PrometheusReleaseKey = "release" ) // defaults From 6c3fc5e1378990a62a15593aa0f50468ce88d158 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 25 Jan 2024 06:17:51 -0500 Subject: [PATCH 66/94] finish repo-server implementation Signed-off-by: Jaideep Rao --- common/envVars.go | 6 +- common/reposerver.go | 9 + controllers/argocd/TOBEREMOVED.go | 10 + .../argocd/applicationset/applicationset.go | 2 + .../argocd/applicationset/deployment.go | 5 +- .../argocd/applicationset/interfaces.go | 5 + controllers/argocd/argocd_controller.go | 1 + controllers/argocd/argocdcommon/commands.go | 16 + controllers/argocd/deployment.go | 10 - controllers/argocd/reposerver/deployment.go | 318 ++++++++---------- .../argocd/reposerver/deployment_test.go | 198 +++++------ controllers/argocd/reposerver/helper.go | 5 +- controllers/argocd/reposerver/reposerver.go | 19 +- .../argocd/reposerver/reposerver_test.go | 90 ++--- controllers/argocd/reposerver/secret_test.go | 64 ++-- controllers/argocd/reposerver/service_test.go | 144 ++++---- .../argocd/reposerver/servicemonitor_test.go | 154 ++++----- main.go | 2 +- pkg/util/log.go | 18 + 19 files changed, 542 insertions(+), 534 deletions(-) create mode 100644 controllers/argocd/applicationset/interfaces.go create mode 100644 controllers/argocd/argocdcommon/commands.go diff --git a/common/envVars.go b/common/envVars.go index 9b8593f28..2b84f20a2 100644 --- a/common/envVars.go +++ b/common/envVars.go @@ -14,10 +14,6 @@ const ( // to used for the Keycloak container. ArgoCDKeycloakImageEnvVar = "ARGOCD_KEYCLOAK_IMAGE" - // ArgoCDRepoImageEnvVar is the environment variable used to get the image - // to used for the Dex container. - ArgoCDRepoImageEnvVar = "ARGOCD_REPOSERVER_IMAGE" - // ArgoCDGrafanaImageEnvVar is the environment variable used to get the image // to used for the Grafana container. ArgoCDGrafanaImageEnvVar = "ARGOCD_GRAFANA_IMAGE" @@ -34,4 +30,6 @@ const ( // ArgoCDLabelSelectorEnvVar is an environment variable that contains the labels used for selective instance reconilliation. ArgoCDLabelSelectorEnvVar = "ARGOCD_LABEL_SELECTOR" + + ArgoCDExecTimeoutEnvVar = "ARGOCD_EXEC_TIMEOUT" ) diff --git a/common/reposerver.go b/common/reposerver.go index ae8a6fba1..75e9027e0 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -7,6 +7,8 @@ const ( // RepoServerComponent is the repo-server control plane component RepoServerComponent = "repo-server" + ArgoCDRepoServerName = "argocd-repo-server" + // ArgoCDRepoServerTLSSecretName is the name of the TLS secret for the repo-server ArgoCDRepoServerTLSSecretName = "argocd-repo-server-tls" ) @@ -33,6 +35,13 @@ const ( DefaultRepoServerPort = 8081 ) +// env vars +const ( + // ArgoCDRepoImageEnvVar is the environment variable used to get the image to be used for + // the repo-server container + ArgoCDRepoImageEnvVar = "ARGOCD_REPOSERVER_IMAGE" +) + // keys const ( RepoTLSCertChangedKey = "repo.tls.cert.changed" diff --git a/controllers/argocd/TOBEREMOVED.go b/controllers/argocd/TOBEREMOVED.go index 0da4a16d6..7208fcf4d 100644 --- a/controllers/argocd/TOBEREMOVED.go +++ b/controllers/argocd/TOBEREMOVED.go @@ -2485,3 +2485,13 @@ func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoproj.ArgoCD) } return r.Client.Create(context.TODO(), sm) } + +// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container +func getArgoCmpServerInitCommand() []string { + cmd := make([]string, 0) + cmd = append(cmd, "cp") + cmd = append(cmd, "-n") + cmd = append(cmd, "/usr/local/bin/argocd") + cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") + return cmd +} diff --git a/controllers/argocd/applicationset/applicationset.go b/controllers/argocd/applicationset/applicationset.go index f7e3a7a6f..ebabed156 100644 --- a/controllers/argocd/applicationset/applicationset.go +++ b/controllers/argocd/applicationset/applicationset.go @@ -18,6 +18,8 @@ type ApplicationSetReconciler struct { Scheme *runtime.Scheme Instance *argoproj.ArgoCD Logger logr.Logger + + RepoServer RepoServerController } var ( diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 073480aec..6da10817e 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -5,7 +5,6 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/reposerver" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/mutation" @@ -184,9 +183,9 @@ func (asr *ApplicationSetReconciler) getArgoApplicationSetCommand() []string { cmd = append(cmd, AppSetController) cmd = append(cmd, ArgoCDRepoServer) - cmd = append(cmd, reposerver.GetRepoServerAddress(resourceName, asr.Instance.Namespace)) + cmd = append(cmd, asr.RepoServer.GetServerAddress()) - cmd = append(cmd, common.LogLevel) + cmd = append(cmd, common.LogLevelCmd) cmd = append(cmd, argoutil.GetLogLevel(asr.Instance.Spec.ApplicationSet.LogLevel)) // ApplicationSet command arguments provided by the user diff --git a/controllers/argocd/applicationset/interfaces.go b/controllers/argocd/applicationset/interfaces.go new file mode 100644 index 000000000..cb6ccded2 --- /dev/null +++ b/controllers/argocd/applicationset/interfaces.go @@ -0,0 +1,5 @@ +package applicationset + +type RepoServerController interface { + GetServerAddress() string +} diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index bd85267b1..58fa040d3 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -625,6 +625,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { r.ReposerverController.Redis = redisController r.AppsetController = appsetController + r.AppsetController.RepoServer = reposerverController r.RedisController = redisController diff --git a/controllers/argocd/argocdcommon/commands.go b/controllers/argocd/argocdcommon/commands.go new file mode 100644 index 000000000..dc42c3817 --- /dev/null +++ b/controllers/argocd/argocdcommon/commands.go @@ -0,0 +1,16 @@ +package argocdcommon + +const ( + ArgoCDBinPath = "/usr/local/bin/argocd" + CmpServerBinPath = "/var/run/argocd/argocd-cmp-server" +) + +// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container +func GetArgoCmpServerInitCommand() []string { + cmd := make([]string, 0) + cmd = append(cmd, "cp") + cmd = append(cmd, "-n") + cmd = append(cmd, ArgoCDBinPath) + cmd = append(cmd, CmpServerBinPath) + return cmd +} diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go index eea4b821b..621d897a4 100644 --- a/controllers/argocd/deployment.go +++ b/controllers/argocd/deployment.go @@ -213,16 +213,6 @@ func getArgoRedisArgs(useTLS bool) []string { return args } -// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container -func getArgoCmpServerInitCommand() []string { - cmd := make([]string, 0) - cmd = append(cmd, "cp") - cmd = append(cmd, "-n") - cmd = append(cmd, "/usr/local/bin/argocd") - cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") - return cmd -} - // getArgoServerCommand will return the command for the ArgoCD server component. func getArgoServerCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { cmd := make([]string, 0) diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 38c3b7f97..4487468ef 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -8,181 +8,140 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + "k8s.io/apimachinery/pkg/util/intstr" + + "github.com/pkg/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" ) -func (rsr *RepoServerReconciler) reconcileDeployment() error { +const ( + redisTLSPath = "/app/config/reposerver/tls/redis" + cmpServerPluginsPath = "/home/argocd/cmp-server/plugins" +) - rsr.Logger.Info("reconciling deployment") +func (rsr *RepoServerReconciler) reconcileDeployment() error { - desiredDeployment := rsr.getDesiredDeployment() - deploymentRequest := rsr.getDeploymentRequest(*desiredDeployment) + deployReq := rsr.getDeploymentRequest() - desiredDeployment, err := workloads.RequestDeployment(deploymentRequest) + desiredDeploy, err := workloads.RequestDeployment(deployReq) if err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - return err + return errors.Wrapf(err, "reconcileDeployment: failed to reconcile deployment %s", desiredDeploy.Name) } - namespace, err := cluster.GetNamespace(rsr.Instance.Namespace, rsr.Client) - if err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to retrieve namespace", "name", rsr.Instance.Namespace) - return err - } - if namespace.DeletionTimestamp != nil { - if err := rsr.deleteDeployment(desiredDeployment.Name, desiredDeployment.Namespace); err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to delete deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - } - return err + if err = controllerutil.SetControllerReference(rsr.Instance, desiredDeploy, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to set owner reference for deployment", "name", desiredDeploy.Name, "namespace", desiredDeploy.Namespace) } - existingDeployment, err := workloads.GetDeployment(desiredDeployment.Name, desiredDeployment.Namespace, rsr.Client) + existingDeploy, err := workloads.GetDeployment(desiredDeploy.Name, desiredDeploy.Namespace, rsr.Client) if err != nil { - if !errors.IsNotFound(err) { - rsr.Logger.Error(err, "reconcileDeployment: failed to retrieve deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - return err - } - - if err = controllerutil.SetControllerReference(rsr.Instance, desiredDeployment, rsr.Scheme); err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to set owner reference for deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + if !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "reconcileDeployment: failed to retrieve deployment %s", desiredDeploy.Name) } - if err = workloads.CreateDeployment(desiredDeployment, rsr.Client); err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to create deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - return err + if err = workloads.CreateDeployment(desiredDeploy, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileDeployment: failed to create deployment %s in namespace %s", desiredDeploy.Name, desiredDeploy.Namespace) } - rsr.Logger.V(0).Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + rsr.Logger.V(0).Info("deployment created", "name", desiredDeploy.Name, "namespace", desiredDeploy.Namespace) return nil } - deploymentChanged := false + + deployChanged := false fieldsToCompare := []struct { existing, desired interface{} extraAction func() }{ - {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, + {&existingDeploy.Spec.Template.Spec.Containers[0].Image, &desiredDeploy.Spec.Template.Spec.Containers[0].Image, func() { - if existingDeployment.Spec.Template.ObjectMeta.Labels == nil { - existingDeployment.Spec.Template.ObjectMeta.Labels = map[string]string{} + if existingDeploy.Spec.Template.ObjectMeta.Labels == nil { + existingDeploy.Spec.Template.ObjectMeta.Labels = map[string]string{} } - existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) + existingDeploy.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, - {&existingDeployment.Spec.Template.Spec.NodeSelector, &desiredDeployment.Spec.Template.Spec.NodeSelector, nil}, - {&existingDeployment.Spec.Template.Spec.Tolerations, &desiredDeployment.Spec.Template.Spec.Tolerations, nil}, - {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, &desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, nil}, - {&existingDeployment.Spec.Template.Spec.InitContainers, &desiredDeployment.Spec.Template.Spec.InitContainers, nil}, - {&existingDeployment.Spec.Template.Spec.AutomountServiceAccountToken, &desiredDeployment.Spec.Template.Spec.AutomountServiceAccountToken, nil}, - {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, - {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, + {&existingDeploy.Spec.Template.Spec.NodeSelector, &desiredDeploy.Spec.Template.Spec.NodeSelector, nil}, + {&existingDeploy.Spec.Template.Spec.Tolerations, &desiredDeploy.Spec.Template.Spec.Tolerations, nil}, + {&existingDeploy.Spec.Template.Spec.Volumes, &desiredDeploy.Spec.Template.Spec.Volumes, nil}, + {&existingDeploy.Spec.Template.Spec.Containers[0].Command, &desiredDeploy.Spec.Template.Spec.Containers[0].Command, nil}, + {&existingDeploy.Spec.Template.Spec.Containers[0].Env, &desiredDeploy.Spec.Template.Spec.Containers[0].Env, nil}, + {&existingDeploy.Spec.Template.Spec.Containers[0].Resources, &desiredDeploy.Spec.Template.Spec.Containers[0].Resources, nil}, + {&existingDeploy.Spec.Template.Spec.Containers[0].VolumeMounts, &desiredDeploy.Spec.Template.Spec.Containers[0].VolumeMounts, nil}, + {&existingDeploy.Spec.Template.Spec.InitContainers, &desiredDeploy.Spec.Template.Spec.InitContainers, nil}, + {&existingDeploy.Spec.Template.Spec.AutomountServiceAccountToken, &desiredDeploy.Spec.Template.Spec.AutomountServiceAccountToken, nil}, + {&existingDeploy.Spec.Template.Spec.ServiceAccountName, &desiredDeploy.Spec.Template.Spec.ServiceAccountName, nil}, + {&existingDeploy.Spec.Replicas, &desiredDeploy.Spec.Replicas, nil}, } for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deploymentChanged) + argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deployChanged) } - if !reflect.DeepEqual(desiredDeployment.Spec.Template.Spec.Containers[1:], existingDeployment.Spec.Template.Spec.Containers[1:]) { - existingDeployment.Spec.Template.Spec.Containers = append(existingDeployment.Spec.Template.Spec.Containers[0:1], - desiredDeployment.Spec.Template.Spec.Containers[1:]...) - deploymentChanged = true + if !reflect.DeepEqual(desiredDeploy.Spec.Template.Spec.Containers[1:], existingDeploy.Spec.Template.Spec.Containers[1:]) { + existingDeploy.Spec.Template.Spec.Containers = append(existingDeploy.Spec.Template.Spec.Containers[0:1], + desiredDeploy.Spec.Template.Spec.Containers[1:]...) + deployChanged = true } - if deploymentChanged { - - if err = workloads.UpdateDeployment(existingDeployment, rsr.Client); err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to update deployment", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) - return err - } + if !deployChanged { + return nil } - rsr.Logger.V(0).Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) - return nil -} - -func (rsr *RepoServerReconciler) deleteDeployment(name, namespace string) error { - if err := workloads.DeleteDeployment(name, namespace, rsr.Client); err != nil { - rsr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) - return err + if err = workloads.UpdateDeployment(existingDeploy, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileDeployment: failed to update deployment %s", existingDeploy.Name) } - rsr.Logger.V(0).Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) + + rsr.Logger.Info("deployment updated", "name", existingDeploy.Name, "namespace", existingDeploy.Namespace) return nil } -func (rsr *RepoServerReconciler) getDesiredDeployment() *appsv1.Deployment { - desiredDeployment := &appsv1.Deployment{} - - automountToken := false - if rsr.Instance.Spec.Repo.MountSAToken { - automountToken = rsr.Instance.Spec.Repo.MountSAToken - } - - objMeta := metav1.ObjectMeta{ - Name: resourceName, - Namespace: rsr.Instance.Namespace, - Labels: resourceLabels, - } - podSpec := corev1.PodSpec{ - Volumes: rsr.getRepoServerPodVolumes(), - InitContainers: rsr.getRepoSeverInitContainers(), - Containers: rsr.getRepoServerContainers(), - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: util.BoolPtr(true), - }, - AutomountServiceAccountToken: &automountToken, - NodeSelector: common.DefaultNodeSelector(), - } - - if rsr.Instance.Spec.NodePlacement != nil { - podSpec.NodeSelector = argoutil.AppendStringMap(podSpec.NodeSelector, rsr.Instance.Spec.NodePlacement.NodeSelector) - podSpec.Tolerations = rsr.Instance.Spec.NodePlacement.Tolerations - } - - if rsr.Instance.Spec.Repo.ServiceAccount != "" { - podSpec.ServiceAccountName = rsr.Instance.Spec.Repo.ServiceAccount - } - - deploymentSpec := appsv1.DeploymentSpec{ - Template: corev1.PodTemplateSpec{ - Spec: podSpec, - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ +func (rsr *RepoServerReconciler) getDeploymentRequest() workloads.DeploymentRequest { + deploymentReq := workloads.DeploymentRequest{ + ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ common.AppK8sKeyName: resourceName, }, }, - }, - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: resourceName, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + common.AppK8sKeyName: resourceName, + }, + }, + Spec: corev1.PodSpec{ + Volumes: rsr.getPodVolumes(), + InitContainers: rsr.getRepoSeverInitContainers(), + Containers: rsr.getContainers(), + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: util.BoolPtr(true), + }, + AutomountServiceAccountToken: &rsr.Instance.Spec.Repo.MountSAToken, + NodeSelector: common.DefaultNodeSelector(), + ServiceAccountName: resourceName, + }, }, }, - Replicas: rsr.GetRepoServerReplicas(), + Instance: rsr.Instance, + Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, + Client: rsr.Client, } - desiredDeployment.ObjectMeta = objMeta - desiredDeployment.Spec = deploymentSpec - return desiredDeployment -} + if rsr.Instance.Spec.Repo.ServiceAccount != "" { + deploymentReq.Spec.Template.Spec.ServiceAccountName = rsr.Instance.Spec.Repo.ServiceAccount + } -func (rsr *RepoServerReconciler) getDeploymentRequest(dep appsv1.Deployment) workloads.DeploymentRequest { - deploymentReq := workloads.DeploymentRequest{ - ObjectMeta: dep.ObjectMeta, - Spec: dep.Spec, - Client: rsr.Client, - Mutations: []mutation.MutateFunc{mutation.ApplyReconcilerMutation}, + if rsr.Instance.Spec.NodePlacement != nil { + deploymentReq.Spec.Template.Spec.NodeSelector = util.MergeMaps(deploymentReq.Spec.Template.Spec.NodeSelector, rsr.Instance.Spec.NodePlacement.NodeSelector) + deploymentReq.Spec.Template.Spec.Tolerations = rsr.Instance.Spec.NodePlacement.Tolerations } return deploymentReq @@ -190,11 +149,11 @@ func (rsr *RepoServerReconciler) getDeploymentRequest(dep appsv1.Deployment) wor func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container { initContainers := []corev1.Container{{ - Name: common.CopyUtil, + Name: "copyutil", Image: argocdcommon.GetArgoContainerImage(rsr.Instance), Command: argocdcommon.GetArgoCmpServerInitCommand(), ImagePullPolicy: corev1.PullAlways, - Resources: rsr.GetRepoServerResources(), + Resources: rsr.getResources(), Env: util.ProxyEnvVars(), SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: util.BoolPtr(false), @@ -207,8 +166,8 @@ func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container }, VolumeMounts: []corev1.VolumeMount{ { - Name: common.VolumeVarFiles, - MountPath: common.VolumeMountPathVarRunArgocd, + Name: "var-files", + MountPath: "var/run/argocd", }, }, }} @@ -218,8 +177,10 @@ func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container return initContainers } -func (rsr *RepoServerReconciler) getRepoServerContainers() []corev1.Container { +func (rsr *RepoServerReconciler) getContainers() []corev1.Container { + // Global proxy env vars go first repoServerEnv := rsr.Instance.Spec.Repo.Env + // Environment specified in the CR take precedence over everything else repoServerEnv = util.EnvMerge(repoServerEnv, util.ProxyEnvVars(), false) if rsr.Instance.Spec.Repo.ExecTimeout != nil { @@ -227,16 +188,16 @@ func (rsr *RepoServerReconciler) getRepoServerContainers() []corev1.Container { } containers := []corev1.Container{{ - Command: rsr.GetRepoServerCommand(useTLSForRedis), + Command: rsr.getArgs(), Image: argocdcommon.GetArgoContainerImage(rsr.Instance), ImagePullPolicy: corev1.PullAlways, - Name: common.RepoServerController, + Name: common.ArgoCDRepoServerName, Env: repoServerEnv, - Resources: rsr.GetRepoServerResources(), + Resources: rsr.getResources(), LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + Port: intstr.FromInt(common.DefaultRepoServerPort), }, }, InitialDelaySeconds: 5, @@ -253,8 +214,8 @@ func (rsr *RepoServerReconciler) getRepoServerContainers() []corev1.Container { }, Ports: []corev1.ContainerPort{ { - ContainerPort: common.ArgoCDDefaultRepoServerPort, - Name: common.Server, + ContainerPort: common.DefaultRepoServerPort, + Name: "server", }, { ContainerPort: common.ArgoCDDefaultRepoMetricsPort, Name: common.ArgoCDMetrics, @@ -269,43 +230,45 @@ func (rsr *RepoServerReconciler) getRepoServerContainers() []corev1.Container { }, RunAsNonRoot: util.BoolPtr(true), }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: common.SSHKnownHosts, - MountPath: common.VolumeMountPathSSH, - }, - { - Name: common.TLSCerts, - MountPath: common.VolumeMountPathTLS, - }, - { - Name: common.GPGKeys, - MountPath: common.VolumeMountPathGPG, - }, - { - Name: common.GPGKeyRing, - MountPath: common.VolumeMountPathGPGKeyring, - }, - { - Name: common.VolumeTmp, - MountPath: common.VolumeMountPathTmp, - }, - { - Name: common.ArgoCDRepoServerTLSSecretName, - MountPath: common.VolumeMountPathRepoServerTLS, - }, - { - Name: common.ArgoCDRedisServerTLSSecretName, - MountPath: common.VolumeMountPathRepoServerTLSRedis, - }, - { - Name: common.VolumeMountPlugins, - MountPath: common.VolumeMountPathPlugins, - }, - }, }} + + volumeMounts := []corev1.VolumeMount{ + { + Name: common.SSHKnownHosts, + MountPath: common.VolumeMountPathSSH, + }, + { + Name: common.TLSCerts, + MountPath: common.VolumeMountPathTLS, + }, + { + Name: common.GPGKeys, + MountPath: common.VolumeMountPathGPG, + }, + { + Name: common.GPGKeyRing, + MountPath: common.VolumeMountPathGPGKeyring, + }, + { + Name: common.VolumeTmp, + MountPath: common.VolumeMountPathTmp, + }, + { + Name: common.ArgoCDRepoServerTLSSecretName, + MountPath: common.VolumeMountPathRepoServerTLS, + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + MountPath: redisTLSPath, + }, + { + Name: "plugins", + MountPath: cmpServerPluginsPath, + }, + } + if rsr.Instance.Spec.Repo.VolumeMounts != nil { - containers[0].VolumeMounts = append(containers[0].VolumeMounts, rsr.Instance.Spec.Repo.VolumeMounts...) + containers[0].VolumeMounts = append(volumeMounts, rsr.Instance.Spec.Repo.VolumeMounts...) } if rsr.Instance.Spec.Repo.SidecarContainers != nil { @@ -315,7 +278,7 @@ func (rsr *RepoServerReconciler) getRepoServerContainers() []corev1.Container { return containers } -func (rsr *RepoServerReconciler) getRepoServerPodVolumes() []corev1.Volume { +func (rsr *RepoServerReconciler) getPodVolumes() []corev1.Volume { volumes := []corev1.Volume{ { Name: common.SSHKnownHosts, @@ -378,13 +341,13 @@ func (rsr *RepoServerReconciler) getRepoServerPodVolumes() []corev1.Volume { }, }, { - Name: common.VolumeVarFiles, + Name: "var-files", VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, }, { - Name: common.VolumeMountPlugins, + Name: "plugins", VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, @@ -396,7 +359,18 @@ func (rsr *RepoServerReconciler) getRepoServerPodVolumes() []corev1.Volume { return volumes } -// TriggerDeploymentRollout starts server deployment rollout by updating the given key +func (rsr *RepoServerReconciler) deleteDeployment(name, namespace string) error { + if err := workloads.DeleteDeployment(name, namespace, rsr.Client); err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return errors.Wrapf(err, "deleteDeployment: failed to delete deployment %s", name) + } + rsr.Logger.V(0).Info("deployment deleted", "name", name, "namespace", namespace) + return nil +} + +// TriggerDeploymentRollout starts repo-server deployment rollout by updating the given key func (rsr *RepoServerReconciler) TriggerDeploymentRollout(name, namespace, key string) error { return argocdcommon.TriggerDeploymentRollout(name, namespace, key, rsr.Client) } diff --git a/controllers/argocd/reposerver/deployment_test.go b/controllers/argocd/reposerver/deployment_test.go index 1588244ae..04e398102 100644 --- a/controllers/argocd/reposerver/deployment_test.go +++ b/controllers/argocd/reposerver/deployment_test.go @@ -1,107 +1,107 @@ package reposerver -import ( - "context" - "testing" +// import ( +// "context" +// "testing" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/stretchr/testify/assert" +// "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" +// "github.com/stretchr/testify/assert" - appsv1 "k8s.io/api/apps/v1" - "k8s.io/apimachinery/pkg/types" -) +// appsv1 "k8s.io/api/apps/v1" +// "k8s.io/apimachinery/pkg/types" +// ) -func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { - resourceName = argocdcommon.TestArgoCDName - resourceLabels = testExpectedLabels - ns := argocdcommon.MakeTestNamespace() - rsr := makeTestRepoServerReconciler(t, ns) +// func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { +// resourceName = argocdcommon.TestArgoCDName +// resourceLabels = testExpectedLabels +// ns := argocdcommon.MakeTestNamespace() +// rsr := makeTestRepoServerReconciler(t, ns) - tests := []struct { - name string - setupClient func(useTLSForRedis bool) *RepoServerReconciler - wantErr bool - useTLSForRedis bool - }{ - { - name: "create a deployment", - setupClient: func(useTLSForRedis bool) *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns) - }, - wantErr: false, - useTLSForRedis: false, - }, - { - name: "update a deployment when doesn't use TLS for Redis", - setupClient: func(useTLSForRedis bool) *RepoServerReconciler { - existingDeployment := rsr.getDesiredDeployment() - outdatedDeployment := existingDeployment - outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" - return makeTestRepoServerReconciler(t, outdatedDeployment, ns) - }, - wantErr: false, - useTLSForRedis: false, - }, - { - name: "update a deployment when use TLS for Redis", - setupClient: func(useTLSForRedis bool) *RepoServerReconciler { - existingDeployment := rsr.getDesiredDeployment() - outdatedDeployment := existingDeployment - outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" - return makeTestRepoServerReconciler(t, outdatedDeployment, ns) - }, - wantErr: false, - useTLSForRedis: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - asr := tt.setupClient(tt.useTLSForRedis) - err := asr.reconcileDeployment() - if (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } +// tests := []struct { +// name string +// setupClient func(useTLSForRedis bool) *RepoServerReconciler +// wantErr bool +// useTLSForRedis bool +// }{ +// { +// name: "create a deployment", +// setupClient: func(useTLSForRedis bool) *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, ns) +// }, +// wantErr: false, +// useTLSForRedis: false, +// }, +// { +// name: "update a deployment when doesn't use TLS for Redis", +// setupClient: func(useTLSForRedis bool) *RepoServerReconciler { +// existingDeployment := rsr.getDesiredDeployment() +// outdatedDeployment := existingDeployment +// outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" +// return makeTestRepoServerReconciler(t, outdatedDeployment, ns) +// }, +// wantErr: false, +// useTLSForRedis: false, +// }, +// { +// name: "update a deployment when use TLS for Redis", +// setupClient: func(useTLSForRedis bool) *RepoServerReconciler { +// existingDeployment := rsr.getDesiredDeployment() +// outdatedDeployment := existingDeployment +// outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" +// return makeTestRepoServerReconciler(t, outdatedDeployment, ns) +// }, +// wantErr: false, +// useTLSForRedis: true, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// asr := tt.setupClient(tt.useTLSForRedis) +// err := asr.reconcileDeployment() +// if (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } - updatedDeployment := &appsv1.Deployment{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: argocdcommon.TestNamespace}, updatedDeployment) - if err != nil { - t.Fatalf("Could not get updated Deployment: %v", err) - } - assert.Equal(t, testServiceAccount, updatedDeployment.Spec.Template.Spec.ServiceAccountName) - }) - } -} +// updatedDeployment := &appsv1.Deployment{} +// err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: argocdcommon.TestNamespace}, updatedDeployment) +// if err != nil { +// t.Fatalf("Could not get updated Deployment: %v", err) +// } +// assert.Equal(t, testServiceAccount, updatedDeployment.Spec.Template.Spec.ServiceAccountName) +// }) +// } +// } -func TestRepoServerReconciler_DeleteDeployment(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "successful delete", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - rsr := tt.setupClient() - if err := rsr.deleteDeployment(resourceName, ns.Name); (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - }) - } -} +// func TestRepoServerReconciler_DeleteDeployment(t *testing.T) { +// ns := argocdcommon.MakeTestNamespace() +// resourceName = argocdcommon.TestArgoCDName +// tests := []struct { +// name string +// setupClient func() *RepoServerReconciler +// wantErr bool +// }{ +// { +// name: "successful delete", +// setupClient: func() *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, ns) +// }, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// rsr := tt.setupClient() +// if err := rsr.deleteDeployment(resourceName, ns.Name); (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } +// }) +// } +// } diff --git a/controllers/argocd/reposerver/helper.go b/controllers/argocd/reposerver/helper.go index 5fffe7069..298253490 100644 --- a/controllers/argocd/reposerver/helper.go +++ b/controllers/argocd/reposerver/helper.go @@ -66,11 +66,10 @@ func (rsr *RepoServerReconciler) getArgs() []string { if rsr.Instance.Spec.Redis.IsEnabled() { cmd = append(cmd, common.RedisCmd, rsr.Redis.GetServerAddress()) + } else { + rsr.Logger.Info("redis is disabled, skipping redis configuration") } - // TO DO: make this a WARN instead - rsr.Logger.Info("redis is disabled, skipping redis configuration") - if rsr.Redis.UseTLS() { cmd = append(cmd, common.RedisUseTLSCmd) if rsr.Instance.Spec.Redis.DisableTLSVerification { diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 5bf73c553..a29f4927b 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -1,9 +1,7 @@ package reposerver import ( - "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -16,7 +14,7 @@ type RepoServerReconciler struct { Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD - Logger logr.Logger + Logger *util.Logger Appcontroller AppController Server ServerController @@ -30,19 +28,24 @@ var ( ) func (rsr *RepoServerReconciler) Reconcile() error { - rsr.Logger = ctrl.Log.WithName(common.RepoServerController).WithValues("instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) + rsr.Logger = util.NewLogger(common.RepoServerController, "instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) component = common.RepoServerComponent resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerSuffix) resourceMetricsName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetricsSuffix) + if err := rsr.reconcileServiceAccount(); err != nil { + rsr.Logger.Error(err, "failed to reconcile serviceaccount") + return err + } + if err := rsr.reconcileService(); err != nil { - rsr.Logger.Info("reconciling repo server service") + rsr.Logger.Error(err, "failed to reconcile service") return err } if rsr.Instance.Spec.Prometheus.Enabled { if err := rsr.reconcileServiceMonitor(); err != nil { - rsr.Logger.Info("reconciling repo server serviceMonitor") + rsr.Logger.Error(err, "failed to reconcile service monitor") return err } } else { @@ -53,12 +56,12 @@ func (rsr *RepoServerReconciler) Reconcile() error { } if err := rsr.reconcileTLSSecret(); err != nil { - rsr.Logger.Info("reconciling repo server tls secret") + rsr.Logger.Error(err, "failed to reconcile TLS secret") return err } if err := rsr.reconcileDeployment(); err != nil { - rsr.Logger.Info("reconciling repo server deployment") + rsr.Logger.Error(err, "failed to reconcile deployment") return err } diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index c8df70647..159775d3e 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -1,47 +1,47 @@ package reposerver -import ( - "testing" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.RepoServerControllerComponent) - -const testServiceAccount = "test-service-account" - -func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoServerReconciler { - s := scheme.Scheme - - assert.NoError(t, monitoringv1.AddToScheme(s)) - assert.NoError(t, argoproj.AddToScheme(s)) - - cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(common.RepoServerControllerComponent) - - return &RepoServerReconciler{ - Client: cl, - Scheme: s, - Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { - a.Spec.Repo = argoproj.ArgoCDRepoSpec{ - ServiceAccount: testServiceAccount, - AutoTLS: common.OpenShift, - } - a.ObjectMeta = metav1.ObjectMeta{ - Name: argocdcommon.TestArgoCDName, - Namespace: argocdcommon.TestNamespace, - UID: argocdcommon.TestUID, - } - }), - Logger: logger, - } -} +// import ( +// "testing" + +// argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" +// "github.com/argoproj-labs/argocd-operator/common" +// "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" +// monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" +// "github.com/stretchr/testify/assert" +// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +// "k8s.io/apimachinery/pkg/runtime" +// "k8s.io/client-go/kubernetes/scheme" +// ctrl "sigs.k8s.io/controller-runtime" +// "sigs.k8s.io/controller-runtime/pkg/client/fake" +// ) + +// var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.RepoServerControllerComponent) + +// const testServiceAccount = "test-service-account" + +// func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoServerReconciler { +// s := scheme.Scheme + +// assert.NoError(t, monitoringv1.AddToScheme(s)) +// assert.NoError(t, argoproj.AddToScheme(s)) + +// cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() +// logger := ctrl.Log.WithName(common.RepoServerControllerComponent) + +// return &RepoServerReconciler{ +// Client: cl, +// Scheme: s, +// Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { +// a.Spec.Repo = argoproj.ArgoCDRepoSpec{ +// ServiceAccount: testServiceAccount, +// AutoTLS: common.OpenShift, +// } +// a.ObjectMeta = metav1.ObjectMeta{ +// Name: argocdcommon.TestArgoCDName, +// Namespace: argocdcommon.TestNamespace, +// UID: argocdcommon.TestUID, +// } +// }), +// Logger: logger, +// } +// } diff --git a/controllers/argocd/reposerver/secret_test.go b/controllers/argocd/reposerver/secret_test.go index 6dd09e9f5..54459aafd 100644 --- a/controllers/argocd/reposerver/secret_test.go +++ b/controllers/argocd/reposerver/secret_test.go @@ -1,37 +1,31 @@ package reposerver -import ( - "testing" - - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" -) - -// reconcileTLSSecret() will be tested in e2e tests -func TestRepoServerReconciler_DeleteSecret(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "successful delete", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - nr := tt.setupClient() - if err := nr.deleteSecret(ns.Name); (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - }) - } -} +// // reconcileTLSSecret() will be tested in e2e tests +// func TestRepoServerReconciler_DeleteSecret(t *testing.T) { +// ns := argocdcommon.MakeTestNamespace() +// tests := []struct { +// name string +// setupClient func() *RepoServerReconciler +// wantErr bool +// }{ +// { +// name: "successful delete", +// setupClient: func() *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, ns) +// }, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// nr := tt.setupClient() +// if err := nr.deleteSecret(ns.Name); (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } +// }) +// } +// } diff --git a/controllers/argocd/reposerver/service_test.go b/controllers/argocd/reposerver/service_test.go index dd84bbaf9..6163e4186 100644 --- a/controllers/argocd/reposerver/service_test.go +++ b/controllers/argocd/reposerver/service_test.go @@ -1,81 +1,71 @@ package reposerver -import ( - "context" - "testing" +// func TestRepoServerReconciler_reconcileTLSService(t *testing.T) { +// ns := argocdcommon.MakeTestNamespace() +// sa := argocdcommon.MakeTestServiceAccount() +// resourceName = argocdcommon.TestArgoCDName - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) +// tests := []struct { +// name string +// setupClient func() *RepoServerReconciler +// wantErr bool +// }{ +// { +// name: "create a Service", +// setupClient: func() *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, ns, sa) +// }, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// rsr := tt.setupClient() +// err := rsr.reconcileService() +// if (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } +// currentService := &corev1.Service{} +// err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) +// if err != nil { +// t.Fatalf("Could not get current Service: %v", err) +// } +// assert.Equal(t, GetServiceSpec().Ports, currentService.Spec.Ports) +// }) +// } +// } -func TestRepoServerReconciler_reconcileTLSService(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName - - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "create a Service", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns, sa) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - rsr := tt.setupClient() - err := rsr.reconcileService() - if (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - currentService := &corev1.Service{} - err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) - if err != nil { - t.Fatalf("Could not get current Service: %v", err) - } - assert.Equal(t, GetServiceSpec().Ports, currentService.Spec.Ports) - }) - } -} - -func TestRepoServerReconciler_DeleteService(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "successful delete", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, sa, ns) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - rsr := tt.setupClient() - if err := rsr.deleteService(resourceName, ns.Name); (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - }) - } -} +// func TestRepoServerReconciler_DeleteService(t *testing.T) { +// ns := argocdcommon.MakeTestNamespace() +// sa := argocdcommon.MakeTestServiceAccount() +// resourceName = argocdcommon.TestArgoCDName +// tests := []struct { +// name string +// setupClient func() *RepoServerReconciler +// wantErr bool +// }{ +// { +// name: "successful delete", +// setupClient: func() *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, sa, ns) +// }, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// rsr := tt.setupClient() +// if err := rsr.deleteService(resourceName, ns.Name); (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } +// }) +// } +// } diff --git a/controllers/argocd/reposerver/servicemonitor_test.go b/controllers/argocd/reposerver/servicemonitor_test.go index 93097590b..fd47ceef5 100644 --- a/controllers/argocd/reposerver/servicemonitor_test.go +++ b/controllers/argocd/reposerver/servicemonitor_test.go @@ -1,84 +1,84 @@ package reposerver -import ( - "context" - "testing" +// import ( +// "context" +// "testing" - "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - "github.com/argoproj-labs/argocd-operator/pkg/argoutil" - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/types" -) +// "github.com/argoproj-labs/argocd-operator/common" +// "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" +// "github.com/argoproj-labs/argocd-operator/pkg/argoutil" +// monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" +// "github.com/stretchr/testify/assert" +// "k8s.io/apimachinery/pkg/types" +// ) -func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() +// func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { +// ns := argocdcommon.MakeTestNamespace() +// sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName +// resourceName = argocdcommon.TestArgoCDName - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "create a ServiceMonitor", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns, sa) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - rsr := tt.setupClient() - err := rsr.reconcileServiceMonitor() - if (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - currentService := &monitoringv1.ServiceMonitor{} - err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetrics), Namespace: argocdcommon.TestNamespace}, currentService) - if err != nil { - t.Fatalf("Could not get current Service: %v", err) - } - assert.Equal(t, common.ArgoCDMetrics, currentService.Spec.Endpoints[0].Port) - }) - } -} +// tests := []struct { +// name string +// setupClient func() *RepoServerReconciler +// wantErr bool +// }{ +// { +// name: "create a ServiceMonitor", +// setupClient: func() *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, ns, sa) +// }, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// rsr := tt.setupClient() +// err := rsr.reconcileServiceMonitor() +// if (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } +// currentService := &monitoringv1.ServiceMonitor{} +// err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetrics), Namespace: argocdcommon.TestNamespace}, currentService) +// if err != nil { +// t.Fatalf("Could not get current Service: %v", err) +// } +// assert.Equal(t, common.ArgoCDMetrics, currentService.Spec.Endpoints[0].Port) +// }) +// } +// } -func TestRepoServerReconciler_DeleteServiceMonitor(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName - tests := []struct { - name string - setupClient func() *RepoServerReconciler - wantErr bool - }{ - { - name: "successful delete", - setupClient: func() *RepoServerReconciler { - return makeTestRepoServerReconciler(t, ns, sa) - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - rsr := tt.setupClient() - if err := rsr.deleteServiceMonitor(resourceName, ns.Name); (err != nil) != tt.wantErr { - if tt.wantErr { - t.Errorf("Expected error but did not get one") - } else { - t.Errorf("Unexpected error: %v", err) - } - } - }) - } -} +// func TestRepoServerReconciler_DeleteServiceMonitor(t *testing.T) { +// ns := argocdcommon.MakeTestNamespace() +// sa := argocdcommon.MakeTestServiceAccount() +// resourceName = argocdcommon.TestArgoCDName +// tests := []struct { +// name string +// setupClient func() *RepoServerReconciler +// wantErr bool +// }{ +// { +// name: "successful delete", +// setupClient: func() *RepoServerReconciler { +// return makeTestRepoServerReconciler(t, ns, sa) +// }, +// wantErr: false, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// rsr := tt.setupClient() +// if err := rsr.deleteServiceMonitor(resourceName, ns.Name); (err != nil) != tt.wantErr { +// if tt.wantErr { +// t.Errorf("Expected error but did not get one") +// } else { +// t.Errorf("Unexpected error: %v", err) +// } +// } +// }) +// } +// } diff --git a/main.go b/main.go index 27eac3c6c..f2170057f 100644 --- a/main.go +++ b/main.go @@ -105,7 +105,7 @@ func main() { "Enabling this will ensure there is only one active controller manager.") flag.BoolVar(&enableHTTP2, "enable-http2", enableHTTP2, "If HTTP/2 should be enabled for the metrics and webhook servers.") flag.BoolVar(&secureMetrics, "metrics-secure", secureMetrics, "If the metrics endpoint should be served securely.") - flag.StringVar(&logLevel, "loglevel", "info", "The desired logger level") + flag.StringVar(&logLevel, "loglevel", "debug", "The desired logger level") opts := ctrlzap.Options{ Development: true, diff --git a/pkg/util/log.go b/pkg/util/log.go index f0cf226d1..1ffd20d0b 100644 --- a/pkg/util/log.go +++ b/pkg/util/log.go @@ -3,9 +3,27 @@ package util import ( "strings" + "github.com/go-logr/logr" "go.uber.org/zap/zapcore" + ctrl "sigs.k8s.io/controller-runtime" ) +type Logger struct { + logr.Logger +} + +func NewLogger(name string, keysAndValues ...interface{}) *Logger { + return &Logger{ + ctrl.Log.WithName(name).WithValues(keysAndValues...), + } +} + +func (logger *Logger) Debug(msg string, keysAndValues ...interface{}) { + lvl := int(-1 * zapcore.DebugLevel) + + logger.V(lvl).Info(msg, keysAndValues...) +} + func GetLogLevel(lvl string) zapcore.Level { switch strings.ToLower(lvl) { case "error": From 5d648bbecc419b4dbab10c5f4b214aad10bc7b88 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 25 Jan 2024 15:40:04 -0500 Subject: [PATCH 67/94] finish implementation for repo-server Signed-off-by: Jaideep Rao --- coding-standards-and-best-practices.md | 4 ++-- controllers/argocd/applicationset/deployment.go | 6 +++--- controllers/argocd/applicationset/role.go | 6 +++--- controllers/argocd/applicationset/rolebinding.go | 6 +++--- controllers/argocd/applicationset/service.go | 4 ++-- .../argocd/applicationset/serviceaccount.go | 4 ++-- controllers/argocd/applicationset/webhookroute.go | 6 +++--- controllers/argocd/argocd_controller.go | 15 +++++++++++---- controllers/argocd/argocdcommon/secret.go | 4 ++++ controllers/argocd/notifications/configmap.go | 4 ++-- controllers/argocd/notifications/deployment.go | 6 +++--- controllers/argocd/notifications/role.go | 6 +++--- controllers/argocd/notifications/rolebinding.go | 6 +++--- controllers/argocd/notifications/secret.go | 4 ++-- .../argocd/notifications/serviceaccount.go | 4 ++-- controllers/argocd/reposerver/deployment.go | 7 ++++--- controllers/argocd/reposerver/secret.go | 11 ++++++----- controllers/argocd/reposerver/service.go | 12 ++++++------ controllers/argocd/reposerver/serviceaccount.go | 7 ++++--- controllers/argocd/reposerver/servicemonitor.go | 7 ++++--- 20 files changed, 72 insertions(+), 57 deletions(-) diff --git a/coding-standards-and-best-practices.md b/coding-standards-and-best-practices.md index 6111d4f56..74124c36c 100644 --- a/coding-standards-and-best-practices.md +++ b/coding-standards-and-best-practices.md @@ -221,11 +221,11 @@ acr.Logger.V(1).Info("reconcileManagedRoles: one or more mutations could not be acr.Logger.V(1).Info("reconcileManagedRoles: skip reconciliation in favor of custom role", "name", customRoleName) ``` -- Use Info level (`Logger.Info` or `Logger.V(0).Info`) for all other info-level logs. Any new action taken by the controller that is critical to normal functioning. +- Use Info level (`Logger.Info` or `Logger.Info`) for all other info-level logs. Any new action taken by the controller that is critical to normal functioning. - - No need to mention function names when logging at `info` level. eg: ``` -acr.Logger.V(0).Info("role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) +acr.Logger.Info("role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) ``` - Only use log statements to log success/error if the function belongs to a controller package and is invoked by the controller. No need to log statements from utility/helper packages. e.g: diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 6da10817e..ddf124d00 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -59,7 +59,7 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { asr.Logger.Error(err, "reconcileDeployment: failed to create deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err } - asr.Logger.V(0).Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + asr.Logger.Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return nil } deploymentChanged := false @@ -98,7 +98,7 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { } } - asr.Logger.V(0).Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + asr.Logger.Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) return nil } @@ -110,7 +110,7 @@ func (asr *ApplicationSetReconciler) deleteDeployment(name, namespace string) er asr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) + asr.Logger.Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/role.go b/controllers/argocd/applicationset/role.go index c6e8f468f..f41f2c656 100644 --- a/controllers/argocd/applicationset/role.go +++ b/controllers/argocd/applicationset/role.go @@ -64,7 +64,7 @@ func (asr *ApplicationSetReconciler) reconcileRole() error { asr.Logger.Error(err, "reconcileRole: failed to create role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return err } - asr.Logger.V(0).Info("reconcileRole: role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) + asr.Logger.Info("reconcileRole: role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return nil } @@ -75,7 +75,7 @@ func (asr *ApplicationSetReconciler) reconcileRole() error { return err } } - asr.Logger.V(0).Info("reconcileRole: role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) + asr.Logger.Info("reconcileRole: role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) return nil } @@ -87,7 +87,7 @@ func (asr *ApplicationSetReconciler) deleteRole(name, namespace string) error { asr.Logger.Error(err, "DeleteRole: failed to delete role", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteRole: role deleted", "name", name, "namespace", namespace) + asr.Logger.Info("DeleteRole: role deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/rolebinding.go b/controllers/argocd/applicationset/rolebinding.go index 852e94d42..4e4b96b63 100644 --- a/controllers/argocd/applicationset/rolebinding.go +++ b/controllers/argocd/applicationset/rolebinding.go @@ -74,7 +74,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { asr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + asr.Logger.Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return nil } @@ -103,7 +103,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { } } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + asr.Logger.Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) return nil } @@ -116,6 +116,6 @@ func (asr *ApplicationSetReconciler) deleteRoleBinding(name, namespace string) e asr.Logger.Error(err, "DeleteRole: failed to delete roleBinding", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteRoleBinding: roleBinding deleted", "name", name, "namespace", namespace) + asr.Logger.Info("DeleteRoleBinding: roleBinding deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/service.go b/controllers/argocd/applicationset/service.go index e4bcf55d9..c1412d70b 100644 --- a/controllers/argocd/applicationset/service.go +++ b/controllers/argocd/applicationset/service.go @@ -64,7 +64,7 @@ func (asr *ApplicationSetReconciler) reconcileService() error { asr.Logger.Error(err, "reconcileService: failed to create service", "name", desiredService.Name, "namespace", desiredService.Namespace) return err } - asr.Logger.V(0).Info("reconcileService: service created", "name", desiredService.Name, "namespace", desiredService.Namespace) + asr.Logger.Info("reconcileService: service created", "name", desiredService.Name, "namespace", desiredService.Namespace) return nil } @@ -79,7 +79,7 @@ func (asr *ApplicationSetReconciler) deleteService(name, namespace string) error asr.Logger.Error(err, "DeleteService: failed to delete service", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteService: service deleted", "name", name, "namespace", namespace) + asr.Logger.Info("DeleteService: service deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/serviceaccount.go b/controllers/argocd/applicationset/serviceaccount.go index b91d93e3a..e631299ba 100644 --- a/controllers/argocd/applicationset/serviceaccount.go +++ b/controllers/argocd/applicationset/serviceaccount.go @@ -52,7 +52,7 @@ func (asr *ApplicationSetReconciler) reconcileServiceAccount() error { asr.Logger.Error(err, "reconcileServiceAccount: failed to create serviceAccount", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return err } - asr.Logger.V(0).Info("reconcileServiceAccount: serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) + asr.Logger.Info("reconcileServiceAccount: serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return nil } @@ -67,6 +67,6 @@ func (nr *ApplicationSetReconciler) deleteServiceAccount(name, namespace string) nr.Logger.Error(err, "DeleteServiceAccount: failed to delete serviceAccount", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteServiceAccount: serviceAccount deleted", "name", name, "namespace", namespace) + nr.Logger.Info("DeleteServiceAccount: serviceAccount deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/webhookroute.go b/controllers/argocd/applicationset/webhookroute.go index 8e41ca612..e74cdd016 100644 --- a/controllers/argocd/applicationset/webhookroute.go +++ b/controllers/argocd/applicationset/webhookroute.go @@ -56,7 +56,7 @@ func (asr *ApplicationSetReconciler) reconcileWebhookRoute() error { asr.Logger.Error(err, "reconcileRoute: failed to create route", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) return err } - asr.Logger.V(0).Info("reconcileRoute: route created", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) + asr.Logger.Info("reconcileRoute: route created", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) return nil } @@ -86,7 +86,7 @@ func (asr *ApplicationSetReconciler) reconcileWebhookRoute() error { } } - asr.Logger.V(0).Info("reconcileRoute: webhook route updated", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) + asr.Logger.Info("reconcileRoute: webhook route updated", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) return nil } @@ -99,7 +99,7 @@ func (asr *ApplicationSetReconciler) deleteWebhookRoute(name, namespace string) asr.Logger.Error(err, "DeleteRoute: failed to delete route", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteRoute: route deleted", "name", name, "namespace", namespace) + asr.Logger.Info("DeleteRoute: route deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 58fa040d3..421278bbd 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -40,6 +40,7 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/monitoring" "github.com/argoproj-labs/argocd-operator/pkg/openshift" + "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -518,12 +519,17 @@ func (r *ArgoCDReconciler) reconcileControllers() error { return err } - if err := r.ReposerverController.Reconcile(); err != nil { - r.Logger.Error(err, "failed to reconcile reposerver controller") - return err + if *r.Instance.Spec.Repo.Enabled { + if err := r.ReposerverController.Reconcile(); err != nil { + r.Logger.Error(err, "failed to reconcile repo-server controller") + return err + } + } else { + if err := r.ReposerverController.DeleteResources(); err != nil { + r.Logger.Error(err, "failed to delete repo-server resources") + } } - // non-core components, don't return reconciliation errors if r.Instance.Spec.ApplicationSet != nil { if err := r.AppsetController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile applicationset controller") @@ -577,6 +583,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, + Logger: util.NewLogger(common.RepoServerController, "instance", r.Instance.Name, "instance-namespace", r.Instance.Namespace), } serverController := &server.ServerReconciler{ diff --git a/controllers/argocd/argocdcommon/secret.go b/controllers/argocd/argocdcommon/secret.go index e6b9f82ec..6fc9a8d53 100644 --- a/controllers/argocd/argocdcommon/secret.go +++ b/controllers/argocd/argocdcommon/secret.go @@ -9,6 +9,7 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/networking" "github.com/argoproj-labs/argocd-operator/pkg/workloads" corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" @@ -20,6 +21,9 @@ func TLSSecretChecksum(secretRef types.NamespacedName, client cntrlClient.Client tlsSecret, err := workloads.GetSecret(secretRef.Name, secretRef.Namespace, client) if err != nil { + if apierrors.IsNotFound(err) { + return "", nil + } return "", err } diff --git a/controllers/argocd/notifications/configmap.go b/controllers/argocd/notifications/configmap.go index c5b635e2b..45bd16364 100644 --- a/controllers/argocd/notifications/configmap.go +++ b/controllers/argocd/notifications/configmap.go @@ -59,7 +59,7 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { nr.Logger.Error(err, "reconcileConfigMap: failed to create configMap", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) return err } - nr.Logger.V(0).Info("reconcileConfigMap: configMap created", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) + nr.Logger.Info("reconcileConfigMap: configMap created", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) return nil } @@ -74,6 +74,6 @@ func (nr *NotificationsReconciler) deleteConfigMap(namespace string) error { nr.Logger.Error(err, "DeleteConfigMap: failed to delete configMap", "name", common.NotificationsConfigMapName, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteConfigMap: configMap deleted", "name", common.NotificationsConfigMapName, "namespace", namespace) + nr.Logger.Info("DeleteConfigMap: configMap deleted", "name", common.NotificationsConfigMapName, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index 8d5f75ee6..3e13f1039 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -60,7 +60,7 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { nr.Logger.Error(err, "reconcileDeployment: failed to create deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err } - nr.Logger.V(0).Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + nr.Logger.Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return nil } deploymentChanged := false @@ -99,7 +99,7 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { } } - nr.Logger.V(0).Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + nr.Logger.Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) return nil } @@ -111,7 +111,7 @@ func (nr *NotificationsReconciler) deleteDeployment(name, namespace string) erro nr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) + nr.Logger.Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/role.go b/controllers/argocd/notifications/role.go index 165f27446..e77e4fe43 100644 --- a/controllers/argocd/notifications/role.go +++ b/controllers/argocd/notifications/role.go @@ -64,7 +64,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { nr.Logger.Error(err, "reconcileRole: failed to create role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return err } - nr.Logger.V(0).Info("reconcileRole: role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) + nr.Logger.Info("reconcileRole: role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return nil } @@ -75,7 +75,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { return err } } - nr.Logger.V(0).Info("reconcileRole: role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) + nr.Logger.Info("reconcileRole: role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) return nil } @@ -87,7 +87,7 @@ func (nr *NotificationsReconciler) deleteRole(name, namespace string) error { nr.Logger.Error(err, "DeleteRole: failed to delete role", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteRole: role deleted", "name", name, "namespace", namespace) + nr.Logger.Info("DeleteRole: role deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/rolebinding.go b/controllers/argocd/notifications/rolebinding.go index ff7c05d9b..15782db46 100644 --- a/controllers/argocd/notifications/rolebinding.go +++ b/controllers/argocd/notifications/rolebinding.go @@ -74,7 +74,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { nr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + nr.Logger.Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return nil } @@ -103,7 +103,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { } } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + nr.Logger.Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) return nil } @@ -116,6 +116,6 @@ func (nr *NotificationsReconciler) deleteRoleBinding(name, namespace string) err nr.Logger.Error(err, "DeleteRole: failed to delete roleBinding", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteRoleBinding: roleBinding deleted", "name", name, "namespace", namespace) + nr.Logger.Info("DeleteRoleBinding: roleBinding deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/secret.go b/controllers/argocd/notifications/secret.go index 6b84f6ac0..5362aac23 100644 --- a/controllers/argocd/notifications/secret.go +++ b/controllers/argocd/notifications/secret.go @@ -61,7 +61,7 @@ func (nr *NotificationsReconciler) reconcileSecret() error { nr.Logger.Error(err, "reconcileSecret: failed to create secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) return err } - nr.Logger.V(0).Info("reconcileSecret: secret created", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + nr.Logger.Info("reconcileSecret: secret created", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) return nil } @@ -76,6 +76,6 @@ func (nr *NotificationsReconciler) deleteSecret(namespace string) error { nr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", common.NotificationsSecretName, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", common.NotificationsSecretName, "namespace", namespace) + nr.Logger.Info("DeleteSecret: secret deleted", "name", common.NotificationsSecretName, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/serviceaccount.go b/controllers/argocd/notifications/serviceaccount.go index 2c9858b4c..c24d4f1a0 100644 --- a/controllers/argocd/notifications/serviceaccount.go +++ b/controllers/argocd/notifications/serviceaccount.go @@ -52,7 +52,7 @@ func (nr *NotificationsReconciler) reconcileServiceAccount() error { nr.Logger.Error(err, "reconcileServiceAccount: failed to create serviceAccount", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return err } - nr.Logger.V(0).Info("reconcileServiceAccount: serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) + nr.Logger.Info("reconcileServiceAccount: serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return nil } @@ -67,6 +67,6 @@ func (nr *NotificationsReconciler) deleteServiceAccount(name, namespace string) nr.Logger.Error(err, "DeleteServiceAccount: failed to delete serviceAccount", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteServiceAccount: serviceAccount deleted", "name", name, "namespace", namespace) + nr.Logger.Info("DeleteServiceAccount: serviceAccount deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 4487468ef..6e10bedb6 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -49,7 +49,7 @@ func (rsr *RepoServerReconciler) reconcileDeployment() error { if err = workloads.CreateDeployment(desiredDeploy, rsr.Client); err != nil { return errors.Wrapf(err, "reconcileDeployment: failed to create deployment %s in namespace %s", desiredDeploy.Name, desiredDeploy.Namespace) } - rsr.Logger.V(0).Info("deployment created", "name", desiredDeploy.Name, "namespace", desiredDeploy.Namespace) + rsr.Logger.Info("deployment created", "name", desiredDeploy.Name, "namespace", desiredDeploy.Namespace) return nil } @@ -364,9 +364,10 @@ func (rsr *RepoServerReconciler) deleteDeployment(name, namespace string) error if apierrors.IsNotFound(err) { return nil } - return errors.Wrapf(err, "deleteDeployment: failed to delete deployment %s", name) + rsr.Logger.Error(err, "deleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) + return err } - rsr.Logger.V(0).Info("deployment deleted", "name", name, "namespace", namespace) + rsr.Logger.Info("deployment deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/secret.go b/controllers/argocd/reposerver/secret.go index 68ab56837..8468c860f 100644 --- a/controllers/argocd/reposerver/secret.go +++ b/controllers/argocd/reposerver/secret.go @@ -26,7 +26,7 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } if sha256sum == "" { - rsr.Logger.V(1).Info("reconcileTLSSecret: received empty checksum; secret of type other than kubernetes.io/tls encountered") + rsr.Logger.Debug("reconcileTLSSecret: received empty checksum; secret either not found, or is of type other than kubernetes.io/tls", "name", common.ArgoCDRepoServerTLSSecretName) return nil } @@ -61,13 +61,14 @@ func (rsr *RepoServerReconciler) reconcileTLSSecret() error { } -func (rr *RepoServerReconciler) deleteSecret(name, namespace string) error { - if err := workloads.DeleteSecret(name, namespace, rr.Client); err != nil { +func (rsr *RepoServerReconciler) deleteSecret(name, namespace string) error { + if err := workloads.DeleteSecret(name, namespace, rsr.Client); err != nil { if apierrors.IsNotFound(err) { return nil } - return errors.Wrapf(err, "deleteSecret: failed to delete secret %s", name) + rsr.Logger.Error(err, "deleteSecret: failed to delete secret", "name", name, "namespace", namespace) + return err } - rr.Logger.V(0).Info("secret deleted", "name", name, "namespace", namespace) + rsr.Logger.Info("secret deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index a2c7dfefa..49bf3aaf8 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -18,9 +18,6 @@ import ( ) func (rsr *RepoServerReconciler) reconcileService() error { - - rsr.Logger.Info("reconciling service") - svcRequest := networking.ServiceRequest{ ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), Spec: corev1.ServiceSpec{ @@ -69,7 +66,7 @@ func (rsr *RepoServerReconciler) reconcileService() error { if err = networking.CreateService(desiredSvc, rsr.Client); err != nil { return errors.Wrapf(err, "reconcileService: failed to create service %s", desiredSvc.Name) } - rsr.Logger.V(0).Info("service created", "name", desiredSvc.Name, "namespace", desiredSvc.Namespace) + rsr.Logger.Info("service created", "name", desiredSvc.Name, "namespace", desiredSvc.Namespace) return nil } @@ -94,15 +91,18 @@ func (rsr *RepoServerReconciler) reconcileService() error { return errors.Wrapf(err, "reconcileService: failed to update service %s", existingSvc.Name) } - rsr.Logger.V(0).Info("service updated", "name", existingSvc.Name, "namespace", existingSvc.Namespace) + rsr.Logger.Info("service updated", "name", existingSvc.Name, "namespace", existingSvc.Namespace) return nil } func (rsr *RepoServerReconciler) deleteService(name, namespace string) error { if err := networking.DeleteService(name, namespace, rsr.Client); err != nil { + if apierrors.IsNotFound(err) { + return nil + } rsr.Logger.Error(err, "DeleteService: failed to delete service", "name", name, "namespace", namespace) return err } - rsr.Logger.V(0).Info("DeleteService: service deleted", "name", name, "namespace", namespace) + rsr.Logger.Info("service deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/serviceaccount.go b/controllers/argocd/reposerver/serviceaccount.go index d875a7e0f..3503d2932 100644 --- a/controllers/argocd/reposerver/serviceaccount.go +++ b/controllers/argocd/reposerver/serviceaccount.go @@ -29,7 +29,7 @@ func (rsr *RepoServerReconciler) reconcileServiceAccount() error { if err = permissions.CreateServiceAccount(desiredSa, rsr.Client); err != nil { return errors.Wrapf(err, "reconcileServiceAccount: failed to create serviceaccount") } - rsr.Logger.V(0).Info("serviceaccount created", "name", desiredSa.Name, "namespace", desiredSa.Namespace) + rsr.Logger.Info("serviceaccount created", "name", desiredSa.Name, "namespace", desiredSa.Namespace) return nil } return nil @@ -40,8 +40,9 @@ func (rsr *RepoServerReconciler) deleteServiceAccount(name, namespace string) er if apierrors.IsNotFound(err) { return nil } - return errors.Wrapf(err, "deleteServiceAccount: failed to delete service account %s", name) + rsr.Logger.Error(err, "deleteServiceAccount: failed to delete serviceaccount", "name", name, "namespace", namespace) + return err } - rsr.Logger.V(0).Info("service account deleted", "name", name, "namespace", namespace) + rsr.Logger.Info("service account deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index 3fb9ce882..bd1043fa2 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -56,7 +56,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { if err = monitoring.CreateServiceMonitor(desiredSM, rsr.Client); err != nil { return errors.Wrapf(err, "reconcileServiceMonitor: failed to create service monitor %s", desiredSM.Name) } - rsr.Logger.V(0).Info("service monitor created", "name", desiredSM.Name, "namespace", desiredSM.Namespace) + rsr.Logger.Info("service monitor created", "name", desiredSM.Name, "namespace", desiredSM.Namespace) return nil } @@ -73,8 +73,9 @@ func (rsr *RepoServerReconciler) deleteServiceMonitor(name, namespace string) er if apierrors.IsNotFound(err) { return nil } - return errors.Wrapf(err, "deleteServiceMonitor: failed to delete service %s", name) + rsr.Logger.Error(err, "DeleteServiceMonitor: failed to delete servicemonitor", "name", name, "namespace", namespace) + return err } - rsr.Logger.V(0).Info("service monitor deleted", "name", name, "namespace", namespace) + rsr.Logger.Info("service monitor deleted", "name", name, "namespace", namespace) return nil } From a89bea4f5afca13f1f314811d50ba1090c8851b5 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Thu, 25 Jan 2024 15:48:40 -0500 Subject: [PATCH 68/94] move repo deployment to toberemoved Signed-off-by: Jaideep Rao --- controllers/argocd/TOBEREMOVED.go | 314 ++++++++++++++++++++++++++++++ controllers/argocd/deployment.go | 314 ------------------------------ 2 files changed, 314 insertions(+), 314 deletions(-) diff --git a/controllers/argocd/TOBEREMOVED.go b/controllers/argocd/TOBEREMOVED.go index 7208fcf4d..f7c628cf5 100644 --- a/controllers/argocd/TOBEREMOVED.go +++ b/controllers/argocd/TOBEREMOVED.go @@ -2495,3 +2495,317 @@ func getArgoCmpServerInitCommand() []string { cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") return cmd } + +// reconcileRepoDeployment will ensure the Deployment resource is present for the ArgoCD Repo component. +func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { + deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) + automountToken := false + if cr.Spec.Repo.MountSAToken { + automountToken = cr.Spec.Repo.MountSAToken + } + + deploy.Spec.Template.Spec.AutomountServiceAccountToken = &automountToken + + if cr.Spec.Repo.ServiceAccount != "" { + deploy.Spec.Template.Spec.ServiceAccountName = cr.Spec.Repo.ServiceAccount + } + + // Global proxy env vars go first + repoEnv := cr.Spec.Repo.Env + // Environment specified in the CR take precedence over everything else + repoEnv = argoutil.EnvMerge(repoEnv, proxyEnvVars(), false) + if cr.Spec.Repo.ExecTimeout != nil { + repoEnv = argoutil.EnvMerge(repoEnv, []corev1.EnvVar{{Name: "ARGOCD_EXEC_TIMEOUT", Value: fmt.Sprintf("%ds", *cr.Spec.Repo.ExecTimeout)}}, true) + } + + AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) + + deploy.Spec.Template.Spec.InitContainers = []corev1.Container{{ + Name: "copyutil", + Image: getArgoContainerImage(cr), + Command: getArgoCmpServerInitCommand(), + ImagePullPolicy: corev1.PullAlways, + Resources: getArgoRepoResources(cr), + Env: proxyEnvVars(), + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "var-files", + MountPath: "/var/run/argocd", + }, + }, + }} + + if cr.Spec.Repo.InitContainers != nil { + deploy.Spec.Template.Spec.InitContainers = append(deploy.Spec.Template.Spec.InitContainers, cr.Spec.Repo.InitContainers...) + } + + repoServerVolumeMounts := []corev1.VolumeMount{ + { + Name: "ssh-known-hosts", + MountPath: "/app/config/ssh", + }, + { + Name: "tls-certs", + MountPath: "/app/config/tls", + }, + { + Name: "gpg-keys", + MountPath: "/app/config/gpg/source", + }, + { + Name: "gpg-keyring", + MountPath: "/app/config/gpg/keys", + }, + { + Name: "tmp", + MountPath: "/tmp", + }, + { + Name: "argocd-repo-server-tls", + MountPath: "/app/config/reposerver/tls", + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + MountPath: "/app/config/reposerver/tls/redis", + }, + { + Name: "plugins", + MountPath: "/home/argocd/cmp-server/plugins", + }, + } + + if cr.Spec.Repo.VolumeMounts != nil { + repoServerVolumeMounts = append(repoServerVolumeMounts, cr.Spec.Repo.VolumeMounts...) + } + + deploy.Spec.Template.Spec.Containers = []corev1.Container{{ + Command: getArgoRepoCommand(cr, useTLSForRedis), + Image: getRepoServerContainerImage(cr), + ImagePullPolicy: corev1.PullAlways, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + Env: repoEnv, + Name: "argocd-repo-server", + Ports: []corev1.ContainerPort{ + { + ContainerPort: common.ArgoCDDefaultRepoServerPort, + Name: "server", + }, { + ContainerPort: common.ArgoCDDefaultRepoMetricsPort, + Name: "metrics", + }, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + Resources: getArgoRepoResources(cr), + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: repoServerVolumeMounts, + }} + + if cr.Spec.Repo.SidecarContainers != nil { + deploy.Spec.Template.Spec.Containers = append(deploy.Spec.Template.Spec.Containers, cr.Spec.Repo.SidecarContainers...) + } + + repoServerVolumes := []corev1.Volume{ + { + Name: "ssh-known-hosts", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDKnownHostsConfigMapName, + }, + }, + }, + }, + { + Name: "tls-certs", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDTLSCertsConfigMapName, + }, + }, + }, + }, + { + Name: "gpg-keys", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDGPGKeysConfigMapName, + }, + }, + }, + }, + { + Name: "gpg-keyring", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "tmp", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "argocd-repo-server-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRepoServerTLSSecretName, + Optional: boolPtr(true), + }, + }, + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRedisServerTLSSecretName, + Optional: boolPtr(true), + }, + }, + }, + { + Name: "var-files", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "plugins", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + } + + if cr.Spec.Repo.Volumes != nil { + repoServerVolumes = append(repoServerVolumes, cr.Spec.Repo.Volumes...) + } + + deploy.Spec.Template.Spec.Volumes = repoServerVolumes + + if replicas := getArgoCDRepoServerReplicas(cr); replicas != nil { + deploy.Spec.Replicas = replicas + } + + existing := newDeploymentWithSuffix("repo-server", "repo-server", cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + + if !cr.Spec.Repo.IsEnabled() { + log.Info("Existing ArgoCD Repo Server found but should be disabled. Deleting Repo Server") + // Delete existing deployment for ArgoCD Repo Server, if any .. + return r.Client.Delete(context.TODO(), existing) + } + + changed := false + actualImage := existing.Spec.Template.Spec.Containers[0].Image + desiredImage := getRepoServerContainerImage(cr) + if actualImage != desiredImage { + existing.Spec.Template.Spec.Containers[0].Image = desiredImage + if existing.Spec.Template.ObjectMeta.Labels == nil { + existing.Spec.Template.ObjectMeta.Labels = map[string]string{ + "image.upgraded": time.Now().UTC().Format("01022006-150406-MST"), + } + } + existing.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") + changed = true + } + updateNodePlacement(existing, deploy, &changed) + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Volumes, existing.Spec.Template.Spec.Volumes) { + existing.Spec.Template.Spec.Volumes = deploy.Spec.Template.Spec.Volumes + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].VolumeMounts, + existing.Spec.Template.Spec.Containers[0].VolumeMounts) { + existing.Spec.Template.Spec.Containers[0].VolumeMounts = deploy.Spec.Template.Spec.Containers[0].VolumeMounts + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Env, + existing.Spec.Template.Spec.Containers[0].Env) { + existing.Spec.Template.Spec.Containers[0].Env = deploy.Spec.Template.Spec.Containers[0].Env + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Resources, existing.Spec.Template.Spec.Containers[0].Resources) { + existing.Spec.Template.Spec.Containers[0].Resources = deploy.Spec.Template.Spec.Containers[0].Resources + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Command, existing.Spec.Template.Spec.Containers[0].Command) { + existing.Spec.Template.Spec.Containers[0].Command = deploy.Spec.Template.Spec.Containers[0].Command + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[1:], + existing.Spec.Template.Spec.Containers[1:]) { + existing.Spec.Template.Spec.Containers = append(existing.Spec.Template.Spec.Containers[0:1], + deploy.Spec.Template.Spec.Containers[1:]...) + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.InitContainers, existing.Spec.Template.Spec.InitContainers) { + existing.Spec.Template.Spec.InitContainers = deploy.Spec.Template.Spec.InitContainers + changed = true + } + + if !reflect.DeepEqual(deploy.Spec.Replicas, existing.Spec.Replicas) { + existing.Spec.Replicas = deploy.Spec.Replicas + changed = true + } + + if deploy.Spec.Template.Spec.AutomountServiceAccountToken != existing.Spec.Template.Spec.AutomountServiceAccountToken { + existing.Spec.Template.Spec.AutomountServiceAccountToken = deploy.Spec.Template.Spec.AutomountServiceAccountToken + changed = true + } + + if deploy.Spec.Template.Spec.ServiceAccountName != existing.Spec.Template.Spec.ServiceAccountName { + existing.Spec.Template.Spec.ServiceAccountName = deploy.Spec.Template.Spec.ServiceAccountName + changed = true + } + + if changed { + return r.Client.Update(context.TODO(), existing) + } + return nil // Deployment found with nothing to do, move along... + } + + if !cr.Spec.Repo.IsEnabled() { + log.Info("ArgoCD Repo Server disabled. Skipping starting ArgoCD Repo Server.") + return nil + } + + if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), deploy) +} diff --git a/controllers/argocd/deployment.go b/controllers/argocd/deployment.go index 621d897a4..8a2c54d3f 100644 --- a/controllers/argocd/deployment.go +++ b/controllers/argocd/deployment.go @@ -811,320 +811,6 @@ func (r *ReconcileArgoCD) reconcileRedisHAProxyDeployment(cr *argoproj.ArgoCD) e return r.Client.Create(context.TODO(), deploy) } -// reconcileRepoDeployment will ensure the Deployment resource is present for the ArgoCD Repo component. -func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { - deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) - automountToken := false - if cr.Spec.Repo.MountSAToken { - automountToken = cr.Spec.Repo.MountSAToken - } - - deploy.Spec.Template.Spec.AutomountServiceAccountToken = &automountToken - - if cr.Spec.Repo.ServiceAccount != "" { - deploy.Spec.Template.Spec.ServiceAccountName = cr.Spec.Repo.ServiceAccount - } - - // Global proxy env vars go first - repoEnv := cr.Spec.Repo.Env - // Environment specified in the CR take precedence over everything else - repoEnv = argoutil.EnvMerge(repoEnv, proxyEnvVars(), false) - if cr.Spec.Repo.ExecTimeout != nil { - repoEnv = argoutil.EnvMerge(repoEnv, []corev1.EnvVar{{Name: "ARGOCD_EXEC_TIMEOUT", Value: fmt.Sprintf("%ds", *cr.Spec.Repo.ExecTimeout)}}, true) - } - - AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) - - deploy.Spec.Template.Spec.InitContainers = []corev1.Container{{ - Name: "copyutil", - Image: getArgoContainerImage(cr), - Command: getArgoCmpServerInitCommand(), - ImagePullPolicy: corev1.PullAlways, - Resources: getArgoRepoResources(cr), - Env: proxyEnvVars(), - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - RunAsNonRoot: boolPtr(true), - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "var-files", - MountPath: "/var/run/argocd", - }, - }, - }} - - if cr.Spec.Repo.InitContainers != nil { - deploy.Spec.Template.Spec.InitContainers = append(deploy.Spec.Template.Spec.InitContainers, cr.Spec.Repo.InitContainers...) - } - - repoServerVolumeMounts := []corev1.VolumeMount{ - { - Name: "ssh-known-hosts", - MountPath: "/app/config/ssh", - }, - { - Name: "tls-certs", - MountPath: "/app/config/tls", - }, - { - Name: "gpg-keys", - MountPath: "/app/config/gpg/source", - }, - { - Name: "gpg-keyring", - MountPath: "/app/config/gpg/keys", - }, - { - Name: "tmp", - MountPath: "/tmp", - }, - { - Name: "argocd-repo-server-tls", - MountPath: "/app/config/reposerver/tls", - }, - { - Name: common.ArgoCDRedisServerTLSSecretName, - MountPath: "/app/config/reposerver/tls/redis", - }, - { - Name: "plugins", - MountPath: "/home/argocd/cmp-server/plugins", - }, - } - - if cr.Spec.Repo.VolumeMounts != nil { - repoServerVolumeMounts = append(repoServerVolumeMounts, cr.Spec.Repo.VolumeMounts...) - } - - deploy.Spec.Template.Spec.Containers = []corev1.Container{{ - Command: getArgoRepoCommand(cr, useTLSForRedis), - Image: getRepoServerContainerImage(cr), - ImagePullPolicy: corev1.PullAlways, - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, - }, - InitialDelaySeconds: 5, - PeriodSeconds: 10, - }, - Env: repoEnv, - Name: "argocd-repo-server", - Ports: []corev1.ContainerPort{ - { - ContainerPort: common.ArgoCDDefaultRepoServerPort, - Name: "server", - }, { - ContainerPort: common.ArgoCDDefaultRepoMetricsPort, - Name: "metrics", - }, - }, - ReadinessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, - }, - InitialDelaySeconds: 5, - PeriodSeconds: 10, - }, - Resources: getArgoRepoResources(cr), - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - RunAsNonRoot: boolPtr(true), - }, - VolumeMounts: repoServerVolumeMounts, - }} - - if cr.Spec.Repo.SidecarContainers != nil { - deploy.Spec.Template.Spec.Containers = append(deploy.Spec.Template.Spec.Containers, cr.Spec.Repo.SidecarContainers...) - } - - repoServerVolumes := []corev1.Volume{ - { - Name: "ssh-known-hosts", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDKnownHostsConfigMapName, - }, - }, - }, - }, - { - Name: "tls-certs", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDTLSCertsConfigMapName, - }, - }, - }, - }, - { - Name: "gpg-keys", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDGPGKeysConfigMapName, - }, - }, - }, - }, - { - Name: "gpg-keyring", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "tmp", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "argocd-repo-server-tls", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: common.ArgoCDRepoServerTLSSecretName, - Optional: boolPtr(true), - }, - }, - }, - { - Name: common.ArgoCDRedisServerTLSSecretName, - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: common.ArgoCDRedisServerTLSSecretName, - Optional: boolPtr(true), - }, - }, - }, - { - Name: "var-files", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "plugins", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - } - - if cr.Spec.Repo.Volumes != nil { - repoServerVolumes = append(repoServerVolumes, cr.Spec.Repo.Volumes...) - } - - deploy.Spec.Template.Spec.Volumes = repoServerVolumes - - if replicas := getArgoCDRepoServerReplicas(cr); replicas != nil { - deploy.Spec.Replicas = replicas - } - - existing := newDeploymentWithSuffix("repo-server", "repo-server", cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { - - if !cr.Spec.Repo.IsEnabled() { - log.Info("Existing ArgoCD Repo Server found but should be disabled. Deleting Repo Server") - // Delete existing deployment for ArgoCD Repo Server, if any .. - return r.Client.Delete(context.TODO(), existing) - } - - changed := false - actualImage := existing.Spec.Template.Spec.Containers[0].Image - desiredImage := getRepoServerContainerImage(cr) - if actualImage != desiredImage { - existing.Spec.Template.Spec.Containers[0].Image = desiredImage - if existing.Spec.Template.ObjectMeta.Labels == nil { - existing.Spec.Template.ObjectMeta.Labels = map[string]string{ - "image.upgraded": time.Now().UTC().Format("01022006-150406-MST"), - } - } - existing.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") - changed = true - } - updateNodePlacement(existing, deploy, &changed) - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Volumes, existing.Spec.Template.Spec.Volumes) { - existing.Spec.Template.Spec.Volumes = deploy.Spec.Template.Spec.Volumes - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].VolumeMounts, - existing.Spec.Template.Spec.Containers[0].VolumeMounts) { - existing.Spec.Template.Spec.Containers[0].VolumeMounts = deploy.Spec.Template.Spec.Containers[0].VolumeMounts - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Env, - existing.Spec.Template.Spec.Containers[0].Env) { - existing.Spec.Template.Spec.Containers[0].Env = deploy.Spec.Template.Spec.Containers[0].Env - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Resources, existing.Spec.Template.Spec.Containers[0].Resources) { - existing.Spec.Template.Spec.Containers[0].Resources = deploy.Spec.Template.Spec.Containers[0].Resources - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Command, existing.Spec.Template.Spec.Containers[0].Command) { - existing.Spec.Template.Spec.Containers[0].Command = deploy.Spec.Template.Spec.Containers[0].Command - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[1:], - existing.Spec.Template.Spec.Containers[1:]) { - existing.Spec.Template.Spec.Containers = append(existing.Spec.Template.Spec.Containers[0:1], - deploy.Spec.Template.Spec.Containers[1:]...) - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.InitContainers, existing.Spec.Template.Spec.InitContainers) { - existing.Spec.Template.Spec.InitContainers = deploy.Spec.Template.Spec.InitContainers - changed = true - } - - if !reflect.DeepEqual(deploy.Spec.Replicas, existing.Spec.Replicas) { - existing.Spec.Replicas = deploy.Spec.Replicas - changed = true - } - - if deploy.Spec.Template.Spec.AutomountServiceAccountToken != existing.Spec.Template.Spec.AutomountServiceAccountToken { - existing.Spec.Template.Spec.AutomountServiceAccountToken = deploy.Spec.Template.Spec.AutomountServiceAccountToken - changed = true - } - - if deploy.Spec.Template.Spec.ServiceAccountName != existing.Spec.Template.Spec.ServiceAccountName { - existing.Spec.Template.Spec.ServiceAccountName = deploy.Spec.Template.Spec.ServiceAccountName - changed = true - } - - if changed { - return r.Client.Update(context.TODO(), existing) - } - return nil // Deployment found with nothing to do, move along... - } - - if !cr.Spec.Repo.IsEnabled() { - log.Info("ArgoCD Repo Server disabled. Skipping starting ArgoCD Repo Server.") - return nil - } - - if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), deploy) -} - // reconcileServerDeployment will ensure the Deployment resource is present for the ArgoCD Server component. func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { deploy := newDeploymentWithSuffix("server", "server", cr) From 9e8feeb98084a96e7df5c84327c3403b080c1f25 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 13:38:25 -0500 Subject: [PATCH 69/94] add global test pkg Signed-off-by: Jaideep Rao --- .../applicationset/applicationset_test.go | 6 +- .../argocd/applicationset/deployment_test.go | 15 +- .../argocd/applicationset/role_test.go | 16 +- .../argocd/applicationset/rolebinding_test.go | 27 +- .../argocd/applicationset/service_test.go | 17 +- .../applicationset/serviceaccount_test.go | 13 +- .../applicationset/webhookroute_test.go | 15 +- controllers/argocd/argocdcommon/testing.go | 69 ---- .../argocd/notifications/configmap_test.go | 8 +- .../argocd/notifications/deployment.go | 4 +- .../argocd/notifications/deployment_test.go | 14 +- .../notifications/notifications_test.go | 16 +- controllers/argocd/notifications/role.go | 4 +- controllers/argocd/notifications/role_test.go | 16 +- .../argocd/notifications/rolebinding.go | 3 +- .../argocd/notifications/rolebinding_test.go | 27 +- controllers/argocd/notifications/secret.go | 3 +- .../argocd/notifications/secret_test.go | 8 +- .../argocd/notifications/serviceaccount.go | 3 +- .../notifications/serviceaccount_test.go | 13 +- pkg/cluster/namespace_test.go | 121 +++--- pkg/monitoring/monitoring_test.go | 26 +- pkg/monitoring/prometheusRule_test.go | 255 ++++-------- pkg/monitoring/serviceMonitor_test.go | 235 ++++------- pkg/networking/ingress_test.go | 115 +++--- pkg/networking/networking_test.go | 17 - pkg/networking/service_test.go | 253 ++++-------- pkg/permissions/clusterrole_test.go | 116 +++--- pkg/permissions/clusterrolebinding_test.go | 92 ++--- pkg/permissions/permissions_test.go | 43 +- pkg/permissions/role_test.go | 153 ++++---- pkg/permissions/rolebinding_test.go | 141 +++---- pkg/permissions/serviceaccount_test.go | 108 +++-- pkg/workloads/configmap_test.go | 180 ++++----- pkg/workloads/deployment_test.go | 166 ++++---- pkg/workloads/hpa_test.go | 148 ++++--- pkg/workloads/secret_test.go | 158 ++++---- pkg/workloads/statefulset_test.go | 156 ++++---- pkg/workloads/workloads_test.go | 37 +- tests/test/testing.go | 370 ++++++++++++++++++ 40 files changed, 1430 insertions(+), 1757 deletions(-) delete mode 100644 controllers/argocd/argocdcommon/testing.go create mode 100644 tests/test/testing.go diff --git a/controllers/argocd/applicationset/applicationset_test.go b/controllers/argocd/applicationset/applicationset_test.go index a504e6084..50ef5f472 100644 --- a/controllers/argocd/applicationset/applicationset_test.go +++ b/controllers/argocd/applicationset/applicationset_test.go @@ -12,10 +12,10 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, AppSetControllerComponent) +var testExpectedLabels = common.DefaultResourceLabels(test.TestArgoCDName, test.TestNamespace, AppSetControllerComponent) func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bool, objs ...runtime.Object) *ApplicationSetReconciler { s := scheme.Scheme @@ -29,7 +29,7 @@ func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bo return &ApplicationSetReconciler{ Client: cl, Scheme: s, - Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { + Instance: test.MakeTestArgoCD(func(a *argoproj.ArgoCD) { a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{ WebhookServer: argoproj.WebhookServerSpec{ Route: argoproj.ArgoCDRouteSpec{ diff --git a/controllers/argocd/applicationset/deployment_test.go b/controllers/argocd/applicationset/deployment_test.go index b4f21d653..edfad7536 100644 --- a/controllers/argocd/applicationset/deployment_test.go +++ b/controllers/argocd/applicationset/deployment_test.go @@ -4,18 +4,17 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/types" ) func TestApplicationSetReconciler_reconcileDeployment(t *testing.T) { - resourceName = argocdcommon.TestArgoCDName + resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() asr := makeTestApplicationSetReconciler(t, false, ns) existingDeployment := asr.getDesiredDeployment() @@ -36,7 +35,7 @@ func TestApplicationSetReconciler_reconcileDeployment(t *testing.T) { name: "update a deployment", setupClient: func() *ApplicationSetReconciler { outdatedDeployment := existingDeployment - outdatedDeployment.ObjectMeta.Labels = argocdcommon.TestKVP + outdatedDeployment.ObjectMeta.Labels = test.TestKVP return makeTestApplicationSetReconciler(t, false, outdatedDeployment, ns) }, wantErr: false, @@ -55,7 +54,7 @@ func TestApplicationSetReconciler_reconcileDeployment(t *testing.T) { } updatedDeployment := &appsv1.Deployment{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: argocdcommon.TestNamespace}, updatedDeployment) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: test.TestNamespace}, updatedDeployment) if err != nil { t.Fatalf("Could not get updated Deployment: %v", err) } @@ -65,8 +64,8 @@ func TestApplicationSetReconciler_reconcileDeployment(t *testing.T) { } func TestApplicationSetReconciler_DeleteDeployment(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *ApplicationSetReconciler diff --git a/controllers/argocd/applicationset/role_test.go b/controllers/argocd/applicationset/role_test.go index a9c421603..e52dca8c3 100644 --- a/controllers/argocd/applicationset/role_test.go +++ b/controllers/argocd/applicationset/role_test.go @@ -10,20 +10,20 @@ import ( "k8s.io/apimachinery/pkg/types" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" ) func TestApplicationSetReconciler_reconcileRole(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName existingRole := &rbacv1.Role{ TypeMeta: metav1.TypeMeta{ Kind: common.RoleKind, APIVersion: common.APIGroupVersionRbacV1, }, ObjectMeta: metav1.ObjectMeta{ - Name: argocdcommon.TestArgoCDName, - Namespace: argocdcommon.TestNamespace, + Name: test.TestArgoCDName, + Namespace: test.TestNamespace, }, Rules: getPolicyRules(), } @@ -63,7 +63,7 @@ func TestApplicationSetReconciler_reconcileRole(t *testing.T) { } updatedRole := &rbacv1.Role{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, updatedRole) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, updatedRole) if err != nil { t.Fatalf("Could not get updated Role: %v", err) } @@ -73,8 +73,8 @@ func TestApplicationSetReconciler_reconcileRole(t *testing.T) { } func TestApplicationSetReconciler_DeleteRole(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *ApplicationSetReconciler diff --git a/controllers/argocd/applicationset/rolebinding_test.go b/controllers/argocd/applicationset/rolebinding_test.go index 67723e656..240670ec3 100644 --- a/controllers/argocd/applicationset/rolebinding_test.go +++ b/controllers/argocd/applicationset/rolebinding_test.go @@ -5,18 +5,21 @@ import ( "testing" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" ) func TestApplicationSetReconciler_reconcileRoleBinding(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName + resourceName = test.TestArgoCDName + ns := test.MakeTestNamespace() + sa := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = resourceName + }) tests := []struct { name string @@ -39,8 +42,8 @@ func TestApplicationSetReconciler_reconcileRoleBinding(t *testing.T) { APIVersion: common.APIGroupVersionRbacV1, }, ObjectMeta: metav1.ObjectMeta{ - Name: argocdcommon.TestArgoCDName, - Namespace: argocdcommon.TestNamespace, + Name: test.TestArgoCDName, + Namespace: test.TestNamespace, }, RoleRef: rbacv1.RoleRef{}, Subjects: []rbacv1.Subject{}, @@ -62,20 +65,20 @@ func TestApplicationSetReconciler_reconcileRoleBinding(t *testing.T) { } } updatedRoleBinding := &rbacv1.RoleBinding{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, updatedRoleBinding) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, updatedRoleBinding) if err != nil { t.Fatalf("Could not get updated RoleBinding: %v", err) } - assert.Equal(t, argocdcommon.TestRoleRef, updatedRoleBinding.RoleRef) - assert.Equal(t, argocdcommon.TestSubjects, updatedRoleBinding.Subjects) + assert.Equal(t, test.MakeTestRoleRef(resourceName), updatedRoleBinding.RoleRef) + assert.Equal(t, test.MakeTestSubjects(types.NamespacedName{Name: resourceName, Namespace: test.TestNamespace}), updatedRoleBinding.Subjects) }) } } func TestApplicationSetReconciler_DeleteRoleBinding(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + sa := test.MakeTestServiceAccount() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *ApplicationSetReconciler diff --git a/controllers/argocd/applicationset/service_test.go b/controllers/argocd/applicationset/service_test.go index f90d8e3fd..815ceec08 100644 --- a/controllers/argocd/applicationset/service_test.go +++ b/controllers/argocd/applicationset/service_test.go @@ -4,17 +4,16 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" ) func TestApplicationSetReconciler_reconcileService(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + sa := test.MakeTestServiceAccount() + resourceName = test.TestArgoCDName tests := []struct { name string @@ -41,7 +40,7 @@ func TestApplicationSetReconciler_reconcileService(t *testing.T) { } } currentService := &corev1.Service{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, currentService) if err != nil { t.Fatalf("Could not get current Service: %v", err) } @@ -51,9 +50,9 @@ func TestApplicationSetReconciler_reconcileService(t *testing.T) { } func TestApplicationSetReconciler_DeleteService(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + sa := test.MakeTestServiceAccount() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *ApplicationSetReconciler diff --git a/controllers/argocd/applicationset/serviceaccount_test.go b/controllers/argocd/applicationset/serviceaccount_test.go index 32d532f2b..769ea2d52 100644 --- a/controllers/argocd/applicationset/serviceaccount_test.go +++ b/controllers/argocd/applicationset/serviceaccount_test.go @@ -4,16 +4,15 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" ) func TestApplicationSetReconciler_reconcileServiceAccount(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels tests := []struct { @@ -42,7 +41,7 @@ func TestApplicationSetReconciler_reconcileServiceAccount(t *testing.T) { } currentServiceAccount := &corev1.ServiceAccount{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentServiceAccount) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, currentServiceAccount) if err != nil { t.Fatalf("Could not get current ServiceAccount: %v", err) } @@ -52,8 +51,8 @@ func TestApplicationSetReconciler_reconcileServiceAccount(t *testing.T) { } func TestApplicationSetReconciler_DeleteServiceAccount(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *ApplicationSetReconciler diff --git a/controllers/argocd/applicationset/webhookroute_test.go b/controllers/argocd/applicationset/webhookroute_test.go index 846136a79..d538df387 100644 --- a/controllers/argocd/applicationset/webhookroute_test.go +++ b/controllers/argocd/applicationset/webhookroute_test.go @@ -4,10 +4,9 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" - routev1 "github.com/openshift/api/route/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -15,7 +14,7 @@ import ( func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { resourceLabels = testExpectedLabels - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() asr := makeTestApplicationSetReconciler(t, true, ns) existingWebhookRoute := asr.getDesiredWebhookRoute() @@ -39,7 +38,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { webhookServerRouteEnabled: true, setupClient: func(webhookServerRouteEnabled bool) *ApplicationSetReconciler { outdatedWebhookRoute := existingWebhookRoute - outdatedWebhookRoute.ObjectMeta.Labels = argocdcommon.TestKVP + outdatedWebhookRoute.ObjectMeta.Labels = test.TestKVP return makeTestApplicationSetReconciler(t, webhookServerRouteEnabled, outdatedWebhookRoute, ns) }, wantErr: false, @@ -58,7 +57,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { } updatedWebhookRoute := &routev1.Route{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, updatedWebhookRoute) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: test.TestNamespace}, updatedWebhookRoute) if err != nil { t.Fatalf("Could not get updated WebhookRoute: %v", err) } @@ -68,7 +67,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { } func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabled(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() tests := []struct { name string @@ -98,7 +97,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabl } webhookRoute := &routev1.Route{} - err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: argocdcommon.TestNamespace}, webhookRoute) + err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: AppSetWebhookRouteName, Namespace: test.TestNamespace}, webhookRoute) if err != nil { assert.Equal(t, errors.IsNotFound(err), true) } @@ -107,7 +106,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabl } func TestApplicationSetReconciler_deleteWebhookRoute(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() tests := []struct { name string webhookServerRouteEnabled bool diff --git a/controllers/argocd/argocdcommon/testing.go b/controllers/argocd/argocdcommon/testing.go deleted file mode 100644 index 11b5b0f50..000000000 --- a/controllers/argocd/argocdcommon/testing.go +++ /dev/null @@ -1,69 +0,0 @@ -package argocdcommon - -import ( - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/common" -) - -const ( - TestNamespace = "argocd" - TestArgoCDName = "argocd" -) - -var ( - TestKey = "test" - TestVal = "test" - TestRoleRef = rbacv1.RoleRef{ - Kind: common.RoleKind, - Name: TestArgoCDName, - APIGroup: rbacv1.GroupName, - } - - TestSubjects = []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: TestArgoCDName, - Namespace: TestNamespace, - }, - } - - TestKVP = map[string]string{ - TestKey: TestVal, - } -) - -func MakeTestNamespace() *corev1.Namespace { - return &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestNamespace, - }, - } -} -func MakeTestServiceAccount() *corev1.ServiceAccount { - return &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestArgoCDName, - Namespace: TestNamespace, - }, - Secrets: []corev1.ObjectReference{}, - } -} - -type argoCDOpt func(*argoproj.ArgoCD) - -func MakeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { - a := &argoproj.ArgoCD{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestArgoCDName, - Namespace: TestNamespace, - }, - } - for _, o := range opts { - o(a) - } - return a -} diff --git a/controllers/argocd/notifications/configmap_test.go b/controllers/argocd/notifications/configmap_test.go index ce148e920..645f71e40 100644 --- a/controllers/argocd/notifications/configmap_test.go +++ b/controllers/argocd/notifications/configmap_test.go @@ -7,14 +7,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ) func TestNotificationsReconciler_reconcileConfigMap(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() tests := []struct { name string @@ -42,7 +42,7 @@ func TestNotificationsReconciler_reconcileConfigMap(t *testing.T) { } currentConfigMap := &corev1.ConfigMap{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: common.NotificationsConfigMapName, Namespace: argocdcommon.TestNamespace}, currentConfigMap) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: common.NotificationsConfigMapName, Namespace: test.TestNamespace}, currentConfigMap) if err != nil { t.Fatalf("Could not get current ConfigMap: %v", err) } @@ -52,7 +52,7 @@ func TestNotificationsReconciler_reconcileConfigMap(t *testing.T) { } func TestNotificationsReconciler_DeleteConfigMap(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index 8d5f75ee6..3b1cbe884 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -12,7 +12,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -47,7 +47,7 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { existingDeployment, err := workloads.GetDeployment(desiredDeployment.Name, desiredDeployment.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { nr.Logger.Error(err, "reconcileDeployment: failed to retrieve deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err } diff --git a/controllers/argocd/notifications/deployment_test.go b/controllers/argocd/notifications/deployment_test.go index 2604003d6..25400f0a6 100644 --- a/controllers/argocd/notifications/deployment_test.go +++ b/controllers/argocd/notifications/deployment_test.go @@ -6,16 +6,16 @@ import ( "github.com/stretchr/testify/assert" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" appsv1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/types" ) func TestNotificationsReconciler_reconcileDeployment(t *testing.T) { - resourceName = argocdcommon.TestArgoCDName + resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() nr := makeTestNotificationsReconciler(t, ns) existingDeployment := nr.getDesiredDeployment() @@ -36,7 +36,7 @@ func TestNotificationsReconciler_reconcileDeployment(t *testing.T) { name: "update a deployment", setupClient: func() *NotificationsReconciler { outdatedDeployment := existingDeployment - outdatedDeployment.ObjectMeta.Labels = argocdcommon.TestKVP + outdatedDeployment.ObjectMeta.Labels = test.TestKVP return makeTestNotificationsReconciler(t, outdatedDeployment, ns) }, wantErr: false, @@ -55,7 +55,7 @@ func TestNotificationsReconciler_reconcileDeployment(t *testing.T) { } updatedDeployment := &appsv1.Deployment{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: argocdcommon.TestNamespace}, updatedDeployment) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: test.TestNamespace}, updatedDeployment) if err != nil { t.Fatalf("Could not get updated Deployment: %v", err) } @@ -65,8 +65,8 @@ func TestNotificationsReconciler_reconcileDeployment(t *testing.T) { } func TestNotificationsReconciler_DeleteDeployment(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/notifications_test.go b/controllers/argocd/notifications/notifications_test.go index c20331b2d..8f5e961f1 100644 --- a/controllers/argocd/notifications/notifications_test.go +++ b/controllers/argocd/notifications/notifications_test.go @@ -11,10 +11,10 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.ArgoCDNotificationsControllerComponent) +var testExpectedLabels = common.DefaultResourceLabels(test.TestArgoCDName, test.TestNamespace, common.ArgoCDNotificationsControllerComponent) func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *NotificationsReconciler { s := scheme.Scheme @@ -26,14 +26,14 @@ func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *Noti return &NotificationsReconciler{ Client: cl, Scheme: s, - Instance: argocdcommon.MakeTestArgoCD(), + Instance: test.MakeTestArgoCD(), Logger: logger, } } func TestNotificationsReconciler_Reconcile(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string resourceName string @@ -42,7 +42,7 @@ func TestNotificationsReconciler_Reconcile(t *testing.T) { }{ { name: "successful reconcile", - resourceName: argocdcommon.TestArgoCDName, + resourceName: test.TestArgoCDName, setupClient: func() *NotificationsReconciler { return makeTestNotificationsReconciler(t, ns) }, @@ -64,7 +64,7 @@ func TestNotificationsReconciler_Reconcile(t *testing.T) { } func TestNotificationsReconciler_DeleteResources(t *testing.T) { - resourceName = argocdcommon.TestArgoCDName + resourceName = test.TestArgoCDName tests := []struct { name string resourceName string @@ -73,7 +73,7 @@ func TestNotificationsReconciler_DeleteResources(t *testing.T) { }{ { name: "successful delete", - resourceName: argocdcommon.TestArgoCDName, + resourceName: test.TestArgoCDName, setupClient: func() *NotificationsReconciler { return makeTestNotificationsReconciler(t) }, diff --git a/controllers/argocd/notifications/role.go b/controllers/argocd/notifications/role.go index 165f27446..83b565a7d 100644 --- a/controllers/argocd/notifications/role.go +++ b/controllers/argocd/notifications/role.go @@ -8,7 +8,7 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/permissions" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -51,7 +51,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { existingRole, err := permissions.GetRole(desiredRole.Name, desiredRole.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { nr.Logger.Error(err, "reconcileRole: failed to retrieve role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return err } diff --git a/controllers/argocd/notifications/role_test.go b/controllers/argocd/notifications/role_test.go index 3f9e73f69..82cda1137 100644 --- a/controllers/argocd/notifications/role_test.go +++ b/controllers/argocd/notifications/role_test.go @@ -10,20 +10,20 @@ import ( "k8s.io/apimachinery/pkg/types" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" ) func TestNotificationsReconciler_reconcileRole(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName existingRole := &rbacv1.Role{ TypeMeta: metav1.TypeMeta{ Kind: common.RoleKind, APIVersion: common.APIGroupVersionRbacV1, }, ObjectMeta: metav1.ObjectMeta{ - Name: argocdcommon.TestArgoCDName, - Namespace: argocdcommon.TestNamespace, + Name: test.TestArgoCDName, + Namespace: test.TestNamespace, }, Rules: getPolicyRules(), } @@ -63,7 +63,7 @@ func TestNotificationsReconciler_reconcileRole(t *testing.T) { } updatedRole := &rbacv1.Role{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, updatedRole) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, updatedRole) if err != nil { t.Fatalf("Could not get updated Role: %v", err) } @@ -73,8 +73,8 @@ func TestNotificationsReconciler_reconcileRole(t *testing.T) { } func TestNotificationsReconciler_DeleteRole(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/rolebinding.go b/controllers/argocd/notifications/rolebinding.go index ff7c05d9b..684770851 100644 --- a/controllers/argocd/notifications/rolebinding.go +++ b/controllers/argocd/notifications/rolebinding.go @@ -7,7 +7,6 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/permissions" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -61,7 +60,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { existingRoleBinding, err := permissions.GetRoleBinding(desiredRoleBinding.Name, desiredRoleBinding.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { nr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } diff --git a/controllers/argocd/notifications/rolebinding_test.go b/controllers/argocd/notifications/rolebinding_test.go index 2eb96d7c4..c29014268 100644 --- a/controllers/argocd/notifications/rolebinding_test.go +++ b/controllers/argocd/notifications/rolebinding_test.go @@ -5,18 +5,21 @@ import ( "testing" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" ) func TestNotificationsReconciler_reconcileRoleBinding(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName + resourceName = test.TestArgoCDName + ns := test.MakeTestNamespace() + sa := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = resourceName + }) tests := []struct { name string @@ -39,8 +42,8 @@ func TestNotificationsReconciler_reconcileRoleBinding(t *testing.T) { APIVersion: common.APIGroupVersionRbacV1, }, ObjectMeta: metav1.ObjectMeta{ - Name: argocdcommon.TestArgoCDName, - Namespace: argocdcommon.TestNamespace, + Name: test.TestArgoCDName, + Namespace: test.TestNamespace, }, RoleRef: rbacv1.RoleRef{}, Subjects: []rbacv1.Subject{}, @@ -62,20 +65,20 @@ func TestNotificationsReconciler_reconcileRoleBinding(t *testing.T) { } } updatedRoleBinding := &rbacv1.RoleBinding{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, updatedRoleBinding) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, updatedRoleBinding) if err != nil { t.Fatalf("Could not get updated RoleBinding: %v", err) } - assert.Equal(t, argocdcommon.TestRoleRef, updatedRoleBinding.RoleRef) - assert.Equal(t, argocdcommon.TestSubjects, updatedRoleBinding.Subjects) + assert.Equal(t, test.MakeTestRoleRef(resourceName), updatedRoleBinding.RoleRef) + assert.Equal(t, test.MakeTestSubjects(types.NamespacedName{Name: resourceName, Namespace: test.TestNamespace}), updatedRoleBinding.Subjects) }) } } func TestNotificationsReconciler_DeleteRoleBinding(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - sa := argocdcommon.MakeTestServiceAccount() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + sa := test.MakeTestServiceAccount() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/secret.go b/controllers/argocd/notifications/secret.go index 6b84f6ac0..8ba710b86 100644 --- a/controllers/argocd/notifications/secret.go +++ b/controllers/argocd/notifications/secret.go @@ -6,7 +6,6 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/workloads" - "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -48,7 +47,7 @@ func (nr *NotificationsReconciler) reconcileSecret() error { _, err = workloads.GetSecret(desiredSecret.Name, desiredSecret.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { nr.Logger.Error(err, "reconcileSecret: failed to retrieve secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) return err } diff --git a/controllers/argocd/notifications/secret_test.go b/controllers/argocd/notifications/secret_test.go index f6b534af9..9350c5d0f 100644 --- a/controllers/argocd/notifications/secret_test.go +++ b/controllers/argocd/notifications/secret_test.go @@ -7,14 +7,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/tests/test" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ) func TestNotificationsReconciler_reconcileSecret(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() resourceLabels = testExpectedLabels tests := []struct { name string @@ -42,7 +42,7 @@ func TestNotificationsReconciler_reconcileSecret(t *testing.T) { } currentSecret := &corev1.Secret{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: common.NotificationsSecretName, Namespace: argocdcommon.TestNamespace}, currentSecret) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: common.NotificationsSecretName, Namespace: test.TestNamespace}, currentSecret) if err != nil { t.Fatalf("Could not get current Secret: %v", err) } @@ -52,7 +52,7 @@ func TestNotificationsReconciler_reconcileSecret(t *testing.T) { } func TestNotificationsReconciler_DeleteSecret(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() + ns := test.MakeTestNamespace() tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/serviceaccount.go b/controllers/argocd/notifications/serviceaccount.go index 2c9858b4c..7ffa648d9 100644 --- a/controllers/argocd/notifications/serviceaccount.go +++ b/controllers/argocd/notifications/serviceaccount.go @@ -4,7 +4,6 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/permissions" - "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -39,7 +38,7 @@ func (nr *NotificationsReconciler) reconcileServiceAccount() error { _, err = permissions.GetServiceAccount(desiredServiceAccount.Name, desiredServiceAccount.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { nr.Logger.Error(err, "reconcileServiceAccount: failed to retrieve serviceAccount", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return err } diff --git a/controllers/argocd/notifications/serviceaccount_test.go b/controllers/argocd/notifications/serviceaccount_test.go index 208918af2..1daf460d1 100644 --- a/controllers/argocd/notifications/serviceaccount_test.go +++ b/controllers/argocd/notifications/serviceaccount_test.go @@ -4,16 +4,15 @@ import ( "context" "testing" + "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" ) func TestNotificationsReconciler_reconcileServiceAccount(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels tests := []struct { @@ -42,7 +41,7 @@ func TestNotificationsReconciler_reconcileServiceAccount(t *testing.T) { } currentServiceAccount := &corev1.ServiceAccount{} - err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentServiceAccount) + err = nr.Client.Get(context.TODO(), types.NamespacedName{Name: test.TestArgoCDName, Namespace: test.TestNamespace}, currentServiceAccount) if err != nil { t.Fatalf("Could not get current ServiceAccount: %v", err) } @@ -52,8 +51,8 @@ func TestNotificationsReconciler_reconcileServiceAccount(t *testing.T) { } func TestNotificationsReconciler_DeleteServiceAccount(t *testing.T) { - ns := argocdcommon.MakeTestNamespace() - resourceName = argocdcommon.TestArgoCDName + ns := test.MakeTestNamespace() + resourceName = test.TestArgoCDName tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/pkg/cluster/namespace_test.go b/pkg/cluster/namespace_test.go index a2743e2a7..d7d85fb0a 100644 --- a/pkg/cluster/namespace_test.go +++ b/pkg/cluster/namespace_test.go @@ -19,53 +19,20 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -var ( - testName = "test-name" - testKey = "test-key" - testVal = "test-value" - testValMutated = "test-value-mutated" - - testKVP = map[string]string{ - testKey: testVal, - } - - testKVPMutated = map[string]string{ - testKey: testValMutated, - } -) - -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return errors.New("test-mutation-error") -} - func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *corev1.Namespace: - if _, ok := obj.Labels[testKey]; ok { - obj.Labels[testKey] = testValMutated + if _, ok := obj.Labels[test.TestKey]; ok { + obj.Labels[test.TestKey] = test.TestValMutated return nil } } return errors.New("test-mutation-error") } -type NamespaceOpt func(*corev1.Namespace) - -func getTestNamespace(opts ...NamespaceOpt) *corev1.Namespace { - desiredNs := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - }, - } - - for _, opt := range opts { - opt(desiredNs) - } - return desiredNs -} - func TestRequestNamespace(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -76,16 +43,16 @@ func TestRequestNamespace(t *testing.T) { wantErr bool }{ { - name: "request namespace, no mutation, custom name, labels, annotations", + name: "request namespace", nsReq: NamespaceRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, + Name: test.TestName, + Labels: test.TestKVP, }, }, - desiredNamespace: getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName - ns.Labels = testKVP + desiredNamespace: test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName + ns.Labels = test.TestKVP }), wantErr: false, }, @@ -93,17 +60,17 @@ func TestRequestNamespace(t *testing.T) { name: "request namespace, successful mutation", nsReq: NamespaceRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, + Name: test.TestName, + Labels: test.TestKVP, }, Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, - desiredNamespace: getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName - ns.Labels = testKVPMutated + desiredNamespace: test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName + ns.Labels = test.TestKVPMutated }), wantErr: false, }, @@ -111,17 +78,17 @@ func TestRequestNamespace(t *testing.T) { name: "request namespace, failed mutation", nsReq: NamespaceRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, + Name: test.TestName, + Labels: test.TestKVP, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredNamespace: getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName - ns.Labels = testKVP + desiredNamespace: test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName + ns.Labels = test.TestKVP }), wantErr: true, }, @@ -144,48 +111,48 @@ func TestRequestNamespace(t *testing.T) { func TestCreateNamespace(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredNamespace := getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName + desiredNamespace := test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName ns.TypeMeta = metav1.TypeMeta{ Kind: "Namespace", APIVersion: "v1", } - ns.Labels = testKVP + ns.Labels = test.TestKVP }) err := CreateNamespace(desiredNamespace, testClient) assert.NoError(t, err) createdNamespace := &corev1.Namespace{} - err = testClient.Get(context.TODO(), cntrlClient.ObjectKey{Name: testName}, createdNamespace) + err = testClient.Get(context.TODO(), cntrlClient.ObjectKey{Name: test.TestName}, createdNamespace) assert.NoError(t, err) assert.Equal(t, desiredNamespace, createdNamespace) } func TestGetNamespace(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName })).Build() - _, err := GetNamespace(testName, testClient) + _, err := GetNamespace(test.TestName, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetNamespace(testName, testClient) + _, err = GetNamespace(test.TestName, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListNamespaces(t *testing.T) { - namespace1 := getTestNamespace(func(ns *corev1.Namespace) { + namespace1 := test.MakeTestNamespace(func(ns *corev1.Namespace) { ns.Name = "namespace-1" ns.Labels = map[string]string{ common.AppK8sKeyComponent: "new-component-1", } }) - namespace2 := getTestNamespace(func(ns *corev1.Namespace) { ns.Name = "namespace-2" }) - namespace3 := getTestNamespace(func(ns *corev1.Namespace) { + namespace2 := test.MakeTestNamespace(func(ns *corev1.Namespace) { ns.Name = "namespace-2" }) + namespace3 := test.MakeTestNamespace(func(ns *corev1.Namespace) { ns.Name = "namespace-3" ns.Labels = map[string]string{ common.AppK8sKeyComponent: "new-component-2", @@ -219,29 +186,29 @@ func TestListNamespaces(t *testing.T) { } func TestUpdateNamespace(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName })).Build() - desiredNamespace := getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName - ns.Labels = testKVP + desiredNamespace := test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName + ns.Labels = test.TestKVP }) err := UpdateNamespace(desiredNamespace, testClient) assert.NoError(t, err) existingNamespace := &corev1.Namespace{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, existingNamespace) assert.NoError(t, err) assert.Equal(t, desiredNamespace.Labels, existingNamespace.Labels) testClient = fake.NewClientBuilder().Build() - existingNamespace = getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName - ns.Labels = testKVP + existingNamespace = test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName + ns.Labels = test.TestKVP }) err = UpdateNamespace(existingNamespace, testClient) assert.Error(t, err) @@ -249,18 +216,18 @@ func TestUpdateNamespace(t *testing.T) { } func TestDeleteNamespace(t *testing.T) { - testNamespace := getTestNamespace(func(ns *corev1.Namespace) { - ns.Name = testName + testNamespace := test.MakeTestNamespace(func(ns *corev1.Namespace) { + ns.Name = test.TestName }) testClient := fake.NewClientBuilder().WithObjects(testNamespace).Build() - err := DeleteNamespace(testName, testClient) + err := DeleteNamespace(test.TestName, testClient) assert.NoError(t, err) existingNamespace := &corev1.Namespace{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, existingNamespace) assert.Error(t, err) diff --git a/pkg/monitoring/monitoring_test.go b/pkg/monitoring/monitoring_test.go index 834b1c34c..734b1eaf6 100644 --- a/pkg/monitoring/monitoring_test.go +++ b/pkg/monitoring/monitoring_test.go @@ -7,36 +7,16 @@ import ( cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -// common test variables used across workloads tests -var ( - testName = "test-name" - testInstance = "test-instance" - testInstanceNamespace = "test-instance-ns" - testNamespace = "test-ns" - testComponent = "test-component" - testKey = "test-key" - testVal = "test-value" - - testPrometheusRuleNameMutated = "mutated-name" - testServiceMonitorNameMutated = "mutated-name" - testKVP = map[string]string{ - testKey: testVal, - } -) - -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return errors.New("test-mutation-error") -} - func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *monitoringv1.PrometheusRule: - obj.Name = testPrometheusRuleNameMutated + obj.Name = test.TestNameMutated return nil case *monitoringv1.ServiceMonitor: - obj.Name = testServiceMonitorNameMutated + obj.Name = test.TestNameMutated return nil } return errors.New("test-mutation-error") diff --git a/pkg/monitoring/prometheusRule_test.go b/pkg/monitoring/prometheusRule_test.go index 5ae8eb674..49eefc715 100644 --- a/pkg/monitoring/prometheusRule_test.go +++ b/pkg/monitoring/prometheusRule_test.go @@ -19,47 +19,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" - "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type prometheusRuleOpt func(*monitoringv1.PrometheusRule) - -func getTestPrometheusRule(opts ...prometheusRuleOpt) *monitoringv1.PrometheusRule { - desiredPrometheusRule := &monitoringv1.PrometheusRule{ - ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: monitoringv1.PrometheusRuleSpec{ - Groups: []monitoringv1.RuleGroup{ - { - Name: common.ArgoCDComponentStatus, - Rules: []monitoringv1.Rule{ - { - Alert: "test alert", - }, - }, - }, - }, - }, - } - - for _, opt := range opts { - opt(desiredPrometheusRule) - } - return desiredPrometheusRule -} - func TestRequestPrometheusRule(t *testing.T) { s := scheme.Scheme @@ -74,76 +36,20 @@ func TestRequestPrometheusRule(t *testing.T) { wantErr bool }{ { - name: "request prometheusRule, no mutation", + name: "request prometheusRule", prometheusRuleReq: PrometheusRuleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: monitoringv1.PrometheusRuleSpec{ - Groups: []monitoringv1.RuleGroup{ - { - Name: common.ArgoCDComponentStatus, - Rules: []monitoringv1.Rule{ - { - Alert: "test alert", - }, - }, - }, - }, - }, - }, - mutation: false, - desiredPrometheusRule: getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) {}), - wantErr: false, - }, - { - name: "request prometheusRule, no mutation, custom name, labels, annotations", - prometheusRuleReq: PrometheusRuleRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - testKey: testVal, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - testKey: testVal, - }, - }, - Spec: monitoringv1.PrometheusRuleSpec{ - Groups: []monitoringv1.RuleGroup{ - { - Name: common.ArgoCDComponentStatus, - Rules: []monitoringv1.Rule{ - { - Alert: "test alert", - }, - }, - }, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, }, mutation: false, - desiredPrometheusRule: getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { - pr.Name = testName - pr.Labels = util.MergeMaps(pr.Labels, testKVP) - pr.Annotations = util.MergeMaps(pr.Annotations, testKVP) + desiredPrometheusRule: test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Labels = test.TestKVP + pr.Annotations = test.TestKVP + }), wantErr: false, }, @@ -151,77 +57,46 @@ func TestRequestPrometheusRule(t *testing.T) { name: "request prometheusRule, successful mutation", prometheusRuleReq: PrometheusRuleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testPrometheusRuleNameMutated, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: monitoringv1.PrometheusRuleSpec{ - Groups: []monitoringv1.RuleGroup{ - { - Name: common.ArgoCDComponentStatus, - Rules: []monitoringv1.Rule{ - { - Alert: "test alert", - }, - }, - }, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, + Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, - mutation: true, - desiredPrometheusRule: getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.Name = testPrometheusRuleNameMutated }), - wantErr: false, + mutation: true, + desiredPrometheusRule: test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Name = test.TestNameMutated + pr.Labels = test.TestKVP + pr.Annotations = test.TestKVP + }), + wantErr: false, }, { name: "request prometheusRule, failed mutation", prometheusRuleReq: PrometheusRuleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: monitoringv1.PrometheusRuleSpec{ - Groups: []monitoringv1.RuleGroup{ - { - Name: common.ArgoCDComponentStatus, - Rules: []monitoringv1.Rule{ - { - Alert: "test alert", - }, - }, - }, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, + Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - mutation: true, - desiredPrometheusRule: getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) {}), - wantErr: true, + mutation: true, + desiredPrometheusRule: test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Labels = test.TestKVP + pr.Annotations = test.TestKVP + }), + wantErr: true, }, } @@ -246,21 +121,23 @@ func TestCreatePrometheusRule(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) testClient := fake.NewClientBuilder().WithScheme(s).Build() - desiredPrometheusRule := getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + desiredPrometheusRule := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.TypeMeta = metav1.TypeMeta{ Kind: "PrometheusRule", APIVersion: "monitoring.coreos.com/v1", } - pr.Name = testName - pr.Namespace = testNamespace + pr.Name = test.TestName + pr.Namespace = test.TestNamespace + pr.Labels = test.TestKVP + pr.Annotations = test.TestKVP }) err := CreatePrometheusRule(desiredPrometheusRule, testClient) assert.NoError(t, err) createdPrometheusRule := &monitoringv1.PrometheusRule{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdPrometheusRule) assert.NoError(t, err) @@ -271,31 +148,31 @@ func TestGetPrometheusRule(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { - pr.Name = testName - pr.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Name = test.TestName + pr.Namespace = test.TestNamespace })).Build() - _, err := GetPrometheusRule(testName, testNamespace, testClient) + _, err := GetPrometheusRule(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().WithScheme(s).Build() - _, err = GetPrometheusRule(testName, testNamespace, testClient) + _, err = GetPrometheusRule(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListPrometheusRules(t *testing.T) { - prometheusRule1 := getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + prometheusRule1 := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-1" - pr.Namespace = testNamespace + pr.Namespace = test.TestNamespace pr.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - prometheusRule2 := getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-2" }) - prometheusRule3 := getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + prometheusRule2 := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-2" }) + prometheusRule3 := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-3" - pr.Namespace = testNamespace + pr.Namespace = test.TestNamespace pr.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -316,7 +193,7 @@ func TestListPrometheusRules(t *testing.T) { desiredPrometheusRules := []string{"prometheusRule-1", "prometheusRule-3"} - existingPrometheusRuleList, err := ListPrometheusRules(testNamespace, testClient, listOpts) + existingPrometheusRuleList, err := ListPrometheusRules(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingPrometheusRules := []string{} @@ -333,9 +210,9 @@ func TestUpdatePrometheusRule(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) // Create the initial PrometheusRule - initialPrometheusRule := getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { - pr.Name = testName - pr.Namespace = testNamespace + initialPrometheusRule := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Name = test.TestName + pr.Namespace = test.TestNamespace }) // Create the client with the initial PrometheusRule @@ -343,7 +220,7 @@ func TestUpdatePrometheusRule(t *testing.T) { // Fetch the PrometheusRule from the client desiredPrometheusRule := &monitoringv1.PrometheusRule{} - err := testClient.Get(context.TODO(), types.NamespacedName{Name: testName, Namespace: testNamespace}, desiredPrometheusRule) + err := testClient.Get(context.TODO(), types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}, desiredPrometheusRule) assert.NoError(t, err) newRuleGroups := []monitoringv1.RuleGroup{ @@ -374,16 +251,16 @@ func TestUpdatePrometheusRule(t *testing.T) { existingPrometheusRule := &monitoringv1.PrometheusRule{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingPrometheusRule) assert.NoError(t, err) assert.Equal(t, desiredPrometheusRule.Spec.Groups, existingPrometheusRule.Spec.Groups) testClient = fake.NewClientBuilder().WithScheme(s).Build() - existingPrometheusRule = getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { - pr.Name = testName + existingPrometheusRule = test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Name = test.TestName pr.Labels = nil }) err = UpdatePrometheusRule(existingPrometheusRule, testClient) @@ -394,20 +271,20 @@ func TestDeletePrometheusRule(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testPrometheusRule := getTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { - pr.Name = testName - pr.Namespace = testNamespace + testPrometheusRule := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + pr.Name = test.TestName + pr.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(testPrometheusRule).Build() - err := DeletePrometheusRule(testName, testNamespace, testClient) + err := DeletePrometheusRule(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingPrometheusRule := &monitoringv1.PrometheusRule{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingPrometheusRule) assert.Error(t, err) diff --git a/pkg/monitoring/serviceMonitor_test.go b/pkg/monitoring/serviceMonitor_test.go index 02a016996..efd36b399 100644 --- a/pkg/monitoring/serviceMonitor_test.go +++ b/pkg/monitoring/serviceMonitor_test.go @@ -17,49 +17,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/argoproj-labs/argocd-operator/common" - "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/mutation" - util "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type serviceMonitorOpt func(*monitoringv1.ServiceMonitor) - -func getTestServiceMonitor(opts ...serviceMonitorOpt) *monitoringv1.ServiceMonitor { - desiredServiceMonitor := &monitoringv1.ServiceMonitor{ - ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: monitoringv1.ServiceMonitorSpec{ - Selector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: argoutil.GenerateResourceName(testInstance, common.ArgoCDMetrics), - }, - }, - Endpoints: []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, - }, - }, - } - - for _, opt := range opts { - opt(desiredServiceMonitor) - } - return desiredServiceMonitor -} - func TestRequestServiceMonitor(t *testing.T) { s := scheme.Scheme @@ -73,74 +34,44 @@ func TestRequestServiceMonitor(t *testing.T) { wantErr bool }{ { - name: "request serviceMonitor, no mutation", + name: "request serviceMonitor", serviceMonitorReq: ServiceMonitorRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: argoutil.GenerateResourceName(testInstance, common.ArgoCDMetrics), - }, - }, - Endpoints: []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, + MatchLabels: test.TestKVP, }, }, }, - desiredServiceMonitor: getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) {}), - wantErr: false, + desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Labels = test.TestKVP + sm.Annotations = test.TestKVP + }), + wantErr: false, }, { - name: "request serviceMonitor, no mutation, custom name, labels, annotations", + name: "request serviceMonitor", serviceMonitorReq: ServiceMonitorRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - testKey: testVal, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - testKey: testVal, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: argoutil.GenerateResourceName(testInstance, common.ArgoCDMetrics), - }, - }, - Endpoints: []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, + MatchLabels: test.TestKVP, }, }, }, - desiredServiceMonitor: getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { - sm.Name = testName - sm.Labels = util.MergeMaps(sm.Labels, testKVP) - sm.Annotations = util.MergeMaps(sm.Annotations, testKVP) + desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Labels = test.TestKVP + sm.Annotations = test.TestKVP }), wantErr: false, }, @@ -148,29 +79,14 @@ func TestRequestServiceMonitor(t *testing.T) { name: "request serviceMonitor, successful mutation", serviceMonitorReq: ServiceMonitorRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testServiceMonitorNameMutated, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: argoutil.GenerateResourceName(testInstance, common.ArgoCDMetrics), - }, - }, - Endpoints: []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, + MatchLabels: test.TestKVP, }, }, Mutations: []mutation.MutateFunc{ @@ -178,44 +94,33 @@ func TestRequestServiceMonitor(t *testing.T) { }, Client: testClient, }, - desiredServiceMonitor: getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.Name = testServiceMonitorNameMutated }), - wantErr: false, + desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Name = test.TestNameMutated + sm.Labels = test.TestKVP + sm.Annotations = test.TestKVP + }), + wantErr: false, }, { name: "request serviceMonitor, failed mutation", serviceMonitorReq: ServiceMonitorRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.AppK8sKeyName: argoutil.GenerateResourceName(testInstance, common.ArgoCDMetrics), - }, - }, - Endpoints: []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, + MatchLabels: test.TestKVP, }, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredServiceMonitor: getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) {}), + desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) {}), wantErr: true, }, } @@ -241,21 +146,23 @@ func TestCreateServiceMonitor(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) testClient := fake.NewClientBuilder().WithScheme(s).Build() - desiredServiceMonitor := getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + desiredServiceMonitor := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.TypeMeta = metav1.TypeMeta{ Kind: "ServiceMonitor", APIVersion: "monitoring.coreos.com/v1", } - sm.Name = testName - sm.Namespace = testNamespace + sm.Name = test.TestName + sm.Namespace = test.TestNamespace + sm.Labels = test.TestKVP + sm.Annotations = test.TestKVP }) err := CreateServiceMonitor(desiredServiceMonitor, testClient) assert.NoError(t, err) createdServiceMonitor := &monitoringv1.ServiceMonitor{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdServiceMonitor) assert.NoError(t, err) @@ -266,31 +173,31 @@ func TestGetServiceMonitor(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { - sm.Name = testName - sm.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Name = test.TestName + sm.Namespace = test.TestNamespace })).Build() - _, err := GetServiceMonitor(testName, testNamespace, testClient) + _, err := GetServiceMonitor(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().WithScheme(s).Build() - _, err = GetServiceMonitor(testName, testNamespace, testClient) + _, err = GetServiceMonitor(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListServiceMonitors(t *testing.T) { - serviceMonitor1 := getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + serviceMonitor1 := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-1" - sm.Namespace = testNamespace + sm.Namespace = test.TestNamespace sm.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - serviceMonitor2 := getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-2" }) - serviceMonitor3 := getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + serviceMonitor2 := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-2" }) + serviceMonitor3 := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-3" - sm.Namespace = testNamespace + sm.Namespace = test.TestNamespace sm.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -311,7 +218,7 @@ func TestListServiceMonitors(t *testing.T) { desiredServiceMonitors := []string{"serviceMonitor-1", "serviceMonitor-3"} - existingServiceMonitorList, err := ListServiceMonitors(testNamespace, testClient, listOpts) + existingServiceMonitorList, err := ListServiceMonitors(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingServiceMonitors := []string{} @@ -328,9 +235,9 @@ func TestUpdateServiceMonitor(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) // Create the initial ServiceMonitor - initialServiceMonitor := getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { - sm.Name = testName - sm.Namespace = testNamespace + initialServiceMonitor := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Name = test.TestName + sm.Namespace = test.TestNamespace }) // Create the client with the initial ServiceMonitor @@ -338,7 +245,7 @@ func TestUpdateServiceMonitor(t *testing.T) { // Fetch the ServiceMonitor from the client desiredServiceMonitor := &monitoringv1.ServiceMonitor{} - err := testClient.Get(context.TODO(), types.NamespacedName{Name: testName, Namespace: testNamespace}, desiredServiceMonitor) + err := testClient.Get(context.TODO(), types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}, desiredServiceMonitor) assert.NoError(t, err) desiredServiceMonitor.Spec.Endpoints = []monitoringv1.Endpoint{ @@ -352,16 +259,16 @@ func TestUpdateServiceMonitor(t *testing.T) { existingServiceMonitor := &monitoringv1.ServiceMonitor{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingServiceMonitor) assert.NoError(t, err) assert.Equal(t, desiredServiceMonitor.Spec.Endpoints, existingServiceMonitor.Spec.Endpoints) testClient = fake.NewClientBuilder().WithScheme(s).Build() - existingServiceMonitor = getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { - sm.Name = testName + existingServiceMonitor = test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Name = test.TestName sm.Labels = nil }) err = UpdateServiceMonitor(existingServiceMonitor, testClient) @@ -372,20 +279,20 @@ func TestDeleteServiceMonitor(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testServiceMonitor := getTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { - sm.Name = testName - sm.Namespace = testNamespace + testServiceMonitor := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + sm.Name = test.TestName + sm.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(testServiceMonitor).Build() - err := DeleteServiceMonitor(testName, testNamespace, testClient) + err := DeleteServiceMonitor(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingServiceMonitor := &monitoringv1.ServiceMonitor{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingServiceMonitor) assert.Error(t, err) diff --git a/pkg/networking/ingress_test.go b/pkg/networking/ingress_test.go index 7ca11b1d9..8311e62fd 100644 --- a/pkg/networking/ingress_test.go +++ b/pkg/networking/ingress_test.go @@ -19,6 +19,7 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" ) type ingressOpt func(*networkingv1.Ingress) @@ -27,17 +28,17 @@ func getTestIngress(opts ...ingressOpt) *networkingv1.Ingress { nginx := "nginx" desiredIngress := &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, + Name: test.TestName, + Namespace: test.TestNamespace, Labels: map[string]string{ - common.AppK8sKeyName: testInstance, + common.AppK8sKeyName: test.TestInstance, common.AppK8sKeyPartOf: common.ArgoCDAppName, common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, + common.AppK8sKeyComponent: test.TestComponent, }, Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, + common.ArgoCDArgoprojKeyName: test.TestInstance, + common.ArgoCDArgoprojKeyNamespace: test.TestInstanceNamespace, }, }, Spec: networkingv1.IngressSpec{ @@ -82,17 +83,17 @@ func TestRequestIngress(t *testing.T) { name: "request ingress, no mutation", ingressReq: IngressRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, + Name: test.TestName, + Namespace: test.TestNamespace, Labels: map[string]string{ - common.AppK8sKeyName: testInstance, + common.AppK8sKeyName: test.TestInstance, common.AppK8sKeyPartOf: common.ArgoCDAppName, common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, + common.AppK8sKeyComponent: test.TestComponent, }, Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, + common.ArgoCDArgoprojKeyName: test.TestInstance, + common.ArgoCDArgoprojKeyNamespace: test.TestInstanceNamespace, }, }, Spec: networkingv1.IngressSpec{ @@ -120,19 +121,19 @@ func TestRequestIngress(t *testing.T) { name: "request ingress, no mutation, custom name, labels, annotations", ingressReq: IngressRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, + Name: test.TestName, + Namespace: test.TestNamespace, Labels: map[string]string{ - common.AppK8sKeyName: testInstance, + common.AppK8sKeyName: test.TestInstance, common.AppK8sKeyPartOf: common.ArgoCDAppName, common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - testKey: testVal, + common.AppK8sKeyComponent: test.TestComponent, + test.TestKey: test.TestVal, }, Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - testKey: testVal, + common.ArgoCDArgoprojKeyName: test.TestInstance, + common.ArgoCDArgoprojKeyNamespace: test.TestInstanceNamespace, + test.TestKey: test.TestVal, }, }, Spec: networkingv1.IngressSpec{ @@ -154,9 +155,9 @@ func TestRequestIngress(t *testing.T) { }, mutation: false, desiredIngress: getTestIngress(func(i *networkingv1.Ingress) { - i.Name = testName - i.Labels = util.MergeMaps(i.Labels, testKVP) - i.Annotations = util.MergeMaps(i.Annotations, testKVP) + i.Name = test.TestName + i.Labels = util.MergeMaps(i.Labels, test.TestKVP) + i.Annotations = util.MergeMaps(i.Annotations, test.TestKVP) }), wantErr: false, }, @@ -165,16 +166,16 @@ func TestRequestIngress(t *testing.T) { ingressReq: IngressRequest{ ObjectMeta: metav1.ObjectMeta{ Name: testIngressNameMutated, - Namespace: testNamespace, + Namespace: test.TestNamespace, Labels: map[string]string{ - common.AppK8sKeyName: testInstance, + common.AppK8sKeyName: test.TestInstance, common.AppK8sKeyPartOf: common.ArgoCDAppName, common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, + common.AppK8sKeyComponent: test.TestComponent, }, Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, + common.ArgoCDArgoprojKeyName: test.TestInstance, + common.ArgoCDArgoprojKeyNamespace: test.TestInstanceNamespace, }, }, Spec: networkingv1.IngressSpec{ @@ -206,17 +207,17 @@ func TestRequestIngress(t *testing.T) { name: "request ingress, failed mutation", ingressReq: IngressRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, + Name: test.TestName, + Namespace: test.TestNamespace, Labels: map[string]string{ - common.AppK8sKeyName: testInstance, + common.AppK8sKeyName: test.TestInstance, common.AppK8sKeyPartOf: common.ArgoCDAppName, common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, + common.AppK8sKeyComponent: test.TestComponent, }, Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, + common.ArgoCDArgoprojKeyName: test.TestInstance, + common.ArgoCDArgoprojKeyNamespace: test.TestInstanceNamespace, }, }, Spec: networkingv1.IngressSpec{ @@ -236,7 +237,7 @@ func TestRequestIngress(t *testing.T) { }, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, @@ -272,16 +273,16 @@ func TestCreateIngress(t *testing.T) { Kind: "Ingress", APIVersion: "networking.k8s.io/v1", } - i.Name = testName - i.Namespace = testNamespace + i.Name = test.TestName + i.Namespace = test.TestNamespace }) err := CreateIngress(desiredIngress, testClient) assert.NoError(t, err) createdIngress := &networkingv1.Ingress{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdIngress) assert.NoError(t, err) @@ -293,16 +294,16 @@ func TestGetIngress(t *testing.T) { assert.NoError(t, networkingv1.AddToScheme(s)) testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(getTestIngress(func(i *networkingv1.Ingress) { - i.Name = testName - i.Namespace = testNamespace + i.Name = test.TestName + i.Namespace = test.TestNamespace })).Build() - _, err := GetIngress(testName, testNamespace, testClient) + _, err := GetIngress(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().WithScheme(s).Build() - _, err = GetIngress(testName, testNamespace, testClient) + _, err = GetIngress(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } @@ -310,13 +311,13 @@ func TestGetIngress(t *testing.T) { func TestListIngresss(t *testing.T) { ingress1 := getTestIngress(func(i *networkingv1.Ingress) { i.Name = "ingress-1" - i.Namespace = testNamespace + i.Namespace = test.TestNamespace i.Labels[common.AppK8sKeyComponent] = "new-component-1" }) ingress2 := getTestIngress(func(i *networkingv1.Ingress) { i.Name = "ingress-2" }) ingress3 := getTestIngress(func(i *networkingv1.Ingress) { i.Name = "ingress-3" - i.Namespace = testNamespace + i.Namespace = test.TestNamespace i.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -337,7 +338,7 @@ func TestListIngresss(t *testing.T) { desiredIngresss := []string{"ingress-1", "ingress-3"} - existingIngressList, err := ListIngresss(testNamespace, testClient, listOpts) + existingIngressList, err := ListIngresss(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingIngresss := []string{} @@ -355,8 +356,8 @@ func TestUpdateIngress(t *testing.T) { // Create the initial Ingress initialIngress := getTestIngress(func(i *networkingv1.Ingress) { - i.Name = testName - i.Namespace = testNamespace + i.Name = test.TestName + i.Namespace = test.TestNamespace }) // Create the client with the initial Ingress @@ -364,7 +365,7 @@ func TestUpdateIngress(t *testing.T) { // Fetch the Ingress from the client desiredIngress := &networkingv1.Ingress{} - err := testClient.Get(context.TODO(), types.NamespacedName{Name: testName, Namespace: testNamespace}, desiredIngress) + err := testClient.Get(context.TODO(), types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}, desiredIngress) assert.NoError(t, err) desiredIngress.Spec.Rules = []networkingv1.IngressRule{ @@ -378,8 +379,8 @@ func TestUpdateIngress(t *testing.T) { existingIngress := &networkingv1.Ingress{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingIngress) assert.NoError(t, err) @@ -387,7 +388,7 @@ func TestUpdateIngress(t *testing.T) { testClient = fake.NewClientBuilder().WithScheme(s).Build() existingIngress = getTestIngress(func(i *networkingv1.Ingress) { - i.Name = testName + i.Name = test.TestName i.Labels = nil }) err = UpdateIngress(existingIngress, testClient) @@ -396,19 +397,19 @@ func TestUpdateIngress(t *testing.T) { func TestDeleteIngress(t *testing.T) { testIngress := getTestIngress(func(i *networkingv1.Ingress) { - i.Name = testName - i.Namespace = testNamespace + i.Name = test.TestName + i.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testIngress).Build() - err := DeleteIngress(testName, testNamespace, testClient) + err := DeleteIngress(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingIngress := &networkingv1.Ingress{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingIngress) assert.Error(t, err) diff --git a/pkg/networking/networking_test.go b/pkg/networking/networking_test.go index 449fc36f8..9f4878c5c 100644 --- a/pkg/networking/networking_test.go +++ b/pkg/networking/networking_test.go @@ -11,29 +11,12 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) -// common test variables used across workloads tests var ( - testName = "test-name" - testInstance = "test-instance" - testInstanceNamespace = "test-instance-ns" - testNamespace = "test-ns" - testComponent = "test-component" - testApplicationName = "test-application-name" - testKey = "test-key" - testVal = "test-value" - testServiceNameMutated = "mutated-name" testRouteNameMutated = "mutated-name" testIngressNameMutated = "mutated-name" - testKVP = map[string]string{ - testKey: testVal, - } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return errors.New("test-mutation-error") -} - func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *corev1.Service: diff --git a/pkg/networking/service_test.go b/pkg/networking/service_test.go index 3f8e2e65e..31d2edda1 100644 --- a/pkg/networking/service_test.go +++ b/pkg/networking/service_test.go @@ -12,52 +12,14 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" - "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type serviceOpt func(*corev1.Service) - -func getTestService(opts ...serviceOpt) *corev1.Service { - desiredService := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: "http", - Protocol: corev1.ProtocolTCP, - Port: 80, - TargetPort: intstr.FromInt(8080), - }, - }, - }, - } - - for _, opt := range opts { - opt(desiredService) - } - return desiredService -} - func TestRequestService(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -70,74 +32,19 @@ func TestRequestService(t *testing.T) { wantErr bool }{ { - name: "request service, no mutation", + name: "request service", deployReq: ServiceRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: "http", - Protocol: corev1.ProtocolTCP, - Port: 80, - TargetPort: intstr.FromInt(8080), - }, - }, - }, - }, - mutation: false, - desiredService: getTestService(func(s *corev1.Service) {}), - wantErr: false, - }, - { - name: "request service, no mutation, custom name, labels, annotations", - deployReq: ServiceRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - testKey: testVal, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - testKey: testVal, - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: "http", - Protocol: corev1.ProtocolTCP, - Port: 80, - TargetPort: intstr.FromInt(8080), - }, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, }, mutation: false, - desiredService: getTestService(func(s *corev1.Service) { - s.Name = testName - s.Labels = util.MergeMaps(s.Labels, testKVP) - s.Annotations = util.MergeMaps(s.Annotations, testKVP) + desiredService: test.MakeTestService(func(s *corev1.Service) { + s.Labels = test.TestKVP + s.Annotations = test.TestKVP }), wantErr: false, }, @@ -145,75 +52,45 @@ func TestRequestService(t *testing.T) { name: "request service, successful mutation", deployReq: ServiceRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testServiceNameMutated, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: "http", - Protocol: corev1.ProtocolTCP, - Port: 80, - TargetPort: intstr.FromInt(8080), - }, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, + Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, - mutation: true, - desiredService: getTestService(func(s *corev1.Service) { s.Name = testServiceNameMutated }), - wantErr: false, + mutation: true, + desiredService: test.MakeTestService(func(s *corev1.Service) { + s.Name = testServiceNameMutated + s.Labels = test.TestKVP + s.Annotations = test.TestKVP + }), + wantErr: false, }, { name: "request service, failed mutation", deployReq: ServiceRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: map[string]string{ - common.AppK8sKeyName: testInstance, - common.AppK8sKeyPartOf: common.ArgoCDAppName, - common.AppK8sKeyManagedBy: common.ArgoCDOperatorName, - common.AppK8sKeyComponent: testComponent, - }, - Annotations: map[string]string{ - common.ArgoCDArgoprojKeyName: testInstance, - common.ArgoCDArgoprojKeyNamespace: testInstanceNamespace, - }, - }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: "http", - Protocol: corev1.ProtocolTCP, - Port: 80, - TargetPort: intstr.FromInt(8080), - }, - }, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - mutation: true, - desiredService: getTestService(func(s *corev1.Service) {}), - wantErr: true, + mutation: true, + desiredService: test.MakeTestService(func(s *corev1.Service) { + s.Labels = test.TestKVP + s.Annotations = test.TestKVP + }), + wantErr: true, }, } @@ -236,21 +113,23 @@ func TestRequestService(t *testing.T) { func TestCreateService(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredService := getTestService(func(s *corev1.Service) { + desiredService := test.MakeTestService(func(s *corev1.Service) { s.TypeMeta = metav1.TypeMeta{ Kind: "Service", APIVersion: "v1", } - s.Name = testName - s.Namespace = testNamespace + s.Name = test.TestName + s.Namespace = test.TestNamespace + s.Labels = test.TestKVP + s.Annotations = test.TestKVP }) err := CreateService(desiredService, testClient) assert.NoError(t, err) createdService := &corev1.Service{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdService) assert.NoError(t, err) @@ -258,29 +137,29 @@ func TestCreateService(t *testing.T) { } func TestGetService(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestService(func(s *corev1.Service) { - s.Name = testName - s.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestService(func(s *corev1.Service) { + s.Name = test.TestName + s.Namespace = test.TestNamespace })).Build() - _, err := GetService(testName, testNamespace, testClient) + _, err := GetService(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetService(testName, testNamespace, testClient) + _, err = GetService(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListServices(t *testing.T) { - service1 := getTestService(func(s *corev1.Service) { + service1 := test.MakeTestService(func(s *corev1.Service) { s.Name = "service-1" - s.Namespace = testNamespace + s.Namespace = test.TestNamespace s.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - service2 := getTestService(func(s *corev1.Service) { s.Name = "service-2" }) - service3 := getTestService(func(s *corev1.Service) { + service2 := test.MakeTestService(func(s *corev1.Service) { s.Name = "service-2" }) + service3 := test.MakeTestService(func(s *corev1.Service) { s.Name = "service-3" s.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -299,7 +178,7 @@ func TestListServices(t *testing.T) { desiredServices := []string{"service-1", "service-3"} - existingServiceList, err := ListServices(testNamespace, testClient, listOpts) + existingServiceList, err := ListServices(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingServices := []string{} @@ -312,14 +191,14 @@ func TestListServices(t *testing.T) { } func TestUpdateService(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestService(func(s *corev1.Service) { - s.Name = testName - s.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestService(func(s *corev1.Service) { + s.Name = test.TestName + s.Namespace = test.TestNamespace })).Build() - desiredService := getTestService(func(s *corev1.Service) { - s.Name = testName - s.Namespace = testNamespace + desiredService := test.MakeTestService(func(s *corev1.Service) { + s.Name = test.TestName + s.Namespace = test.TestNamespace s.Labels = map[string]string{ "control-plane": "argocd-operator", } @@ -329,37 +208,37 @@ func TestUpdateService(t *testing.T) { existingService := &corev1.Service{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingService) assert.NoError(t, err) assert.Equal(t, desiredService.Labels, existingService.Labels) testClient = fake.NewClientBuilder().Build() - existingService = getTestService(func(s *corev1.Service) { - s.Name = testName - s.Namespace = testNamespace + existingService = test.MakeTestService(func(s *corev1.Service) { + s.Name = test.TestName + s.Namespace = test.TestNamespace }) err = UpdateService(existingService, testClient) assert.Error(t, err) } func TestDeleteService(t *testing.T) { - testService := getTestService(func(s *corev1.Service) { - s.Name = testName - s.Namespace = testNamespace + testService := test.MakeTestService(func(s *corev1.Service) { + s.Name = test.TestName + s.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testService).Build() - err := DeleteService(testName, testNamespace, testClient) + err := DeleteService(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingService := &corev1.Service{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingService) assert.Error(t, err) diff --git a/pkg/permissions/clusterrole_test.go b/pkg/permissions/clusterrole_test.go index 231c79748..cfe948bed 100644 --- a/pkg/permissions/clusterrole_test.go +++ b/pkg/permissions/clusterrole_test.go @@ -17,25 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type clusterRoleOpt func(*rbacv1.ClusterRole) - -func getTestClusterRole(opts ...clusterRoleOpt) *rbacv1.ClusterRole { - desiredClusterClusterRole := &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Rules: testRules, - } - - for _, opt := range opts { - opt(desiredClusterClusterRole) - } - return desiredClusterClusterRole -} - func TestRequestClusterClusterRole(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -48,20 +32,20 @@ func TestRequestClusterClusterRole(t *testing.T) { wantErr bool }{ { - name: "request clusterrole, no mutation, custom name, labels, annotations", + name: "request clusterrole", rolReq: ClusterRoleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Rules: testRules, + Rules: test.TestRules, }, mutation: false, - desiredClusterRole: getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName - r.Labels = testKVP - r.Annotations = testKVP + desiredClusterRole: test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName + r.Labels = test.TestKVP + r.Annotations = test.TestKVP }), wantErr: false, }, @@ -69,21 +53,21 @@ func TestRequestClusterClusterRole(t *testing.T) { name: "request clusterrole, successful mutation", rolReq: ClusterRoleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Rules: testRules, + Rules: test.TestRules, Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, mutation: true, - desiredClusterRole: getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName - r.Labels = testKVP - r.Annotations = testKVP + desiredClusterRole: test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName + r.Labels = test.TestKVP + r.Annotations = test.TestKVP r.Rules = testRulesMutated }), wantErr: false, @@ -92,21 +76,21 @@ func TestRequestClusterClusterRole(t *testing.T) { name: "request clusterrole, failed mutation", rolReq: ClusterRoleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Rules: testRules, + Rules: test.TestRules, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, mutation: true, - desiredClusterRole: getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName - r.Labels = testKVP - r.Annotations = testKVP + desiredClusterRole: test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName + r.Labels = test.TestKVP + r.Annotations = test.TestKVP }), wantErr: true, }, @@ -131,48 +115,48 @@ func TestRequestClusterClusterRole(t *testing.T) { func TestCreateClusterRole(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredClusterRole := getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName + desiredClusterRole := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName r.TypeMeta = metav1.TypeMeta{ Kind: "ClusterRole", APIVersion: "rbac.authorization.k8s.io/v1", } - r.Labels = testKVP - r.Annotations = testKVP + r.Labels = test.TestKVP + r.Annotations = test.TestKVP }) err := CreateClusterRole(desiredClusterRole, testClient) assert.NoError(t, err) createdClusterRole := &rbacv1.ClusterRole{} - err = testClient.Get(context.TODO(), cntrlClient.ObjectKey{Name: testName}, createdClusterRole) + err = testClient.Get(context.TODO(), cntrlClient.ObjectKey{Name: test.TestName}, createdClusterRole) assert.NoError(t, err) assert.Equal(t, desiredClusterRole, createdClusterRole) } func TestGetClusterRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName })).Build() - _, err := GetClusterRole(testName, testClient) + _, err := GetClusterRole(test.TestName, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetClusterRole(testName, testClient) + _, err = GetClusterRole(test.TestName, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListClusterRoles(t *testing.T) { - role1 := getTestClusterRole(func(r *rbacv1.ClusterRole) { + role1 := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { r.Name = "role-1" r.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - role2 := getTestClusterRole(func(r *rbacv1.ClusterRole) { r.Name = "role-2" }) - role3 := getTestClusterRole(func(r *rbacv1.ClusterRole) { + role2 := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { r.Name = "role-2" }) + role3 := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { r.Name = "role-3" r.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -204,12 +188,12 @@ func TestListClusterRoles(t *testing.T) { } func TestUpdateClusterRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName })).Build() - desiredClusterRole := getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName + desiredClusterRole := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName r.Rules = testRulesMutated }) err := UpdateClusterRole(desiredClusterRole, testClient) @@ -217,33 +201,33 @@ func TestUpdateClusterRole(t *testing.T) { existingClusterRole := &rbacv1.ClusterRole{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, existingClusterRole) assert.NoError(t, err) assert.Equal(t, desiredClusterRole.Rules, existingClusterRole.Rules) testClient = fake.NewClientBuilder().Build() - existingClusterRole = getTestClusterRole(func(cr *rbacv1.ClusterRole) { - cr.Name = testName + existingClusterRole = test.MakeTestClusterRole(func(cr *rbacv1.ClusterRole) { + cr.Name = test.TestName }) err = UpdateClusterRole(existingClusterRole, testClient) assert.Error(t, err) } func TestDeleteClusterRole(t *testing.T) { - testClusterRole := getTestClusterRole(func(r *rbacv1.ClusterRole) { - r.Name = testName + testClusterRole := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + r.Name = test.TestName }) testClient := fake.NewClientBuilder().WithObjects(testClusterRole).Build() - err := DeleteClusterRole(testName, testClient) + err := DeleteClusterRole(test.TestName, testClient) assert.NoError(t, err) existingClusterRole := &rbacv1.ClusterRole{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, existingClusterRole) assert.Error(t, err) diff --git a/pkg/permissions/clusterrolebinding_test.go b/pkg/permissions/clusterrolebinding_test.go index 9a104737d..210ac120b 100644 --- a/pkg/permissions/clusterrolebinding_test.go +++ b/pkg/permissions/clusterrolebinding_test.go @@ -16,24 +16,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type clusterRoleBindingOpt func(*rbacv1.ClusterRoleBinding) - -func getTestClusterRoleBinding(opts ...clusterRoleBindingOpt) *rbacv1.ClusterRoleBinding { - desiredClusterRoleBinding := &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - - for _, opt := range opts { - opt(desiredClusterRoleBinding) - } - return desiredClusterRoleBinding -} - func TestRequestClusterRoleBinding(t *testing.T) { tests := []struct { name string @@ -42,24 +27,23 @@ func TestRequestClusterRoleBinding(t *testing.T) { }{ { - name: "request clusterrolebinding, custom name, labels, annotations", + name: "request clusterrolebinding", crbReq: ClusterRoleBindingRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - RoleRef: testRoleRef, - Subjects: testSubjects, + RoleRef: test.MakeTestRoleRef(test.TestName), + Subjects: test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}), }, - desiredCrb: getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { - crb.Name = testName - crb.Labels = testKVP - crb.Annotations = testKVP - crb.RoleRef = testRoleRef - crb.Subjects = testSubjects - + desiredCrb: test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb.Name = test.TestName + crb.Labels = test.TestKVP + crb.Annotations = test.TestKVP + crb.RoleRef = test.MakeTestRoleRef(test.TestName) + crb.Subjects = test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}) }), }, } @@ -75,21 +59,21 @@ func TestRequestClusterRoleBinding(t *testing.T) { func TestCreateClusterRoleBinding(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredClusterRoleBinding := getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + desiredClusterRoleBinding := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { crb.TypeMeta = metav1.TypeMeta{ Kind: "ClusterRoleBinding", APIVersion: "rbac.authorization.k8s.io/v1", } - crb.Name = testName - crb.Labels = testKVP - crb.Annotations = testKVP + crb.Name = test.TestName + crb.Labels = test.TestKVP + crb.Annotations = test.TestKVP }) err := CreateClusterRoleBinding(desiredClusterRoleBinding, testClient) assert.NoError(t, err) createdClusterRoleBinding := &rbacv1.ClusterRoleBinding{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, createdClusterRoleBinding) assert.NoError(t, err) @@ -97,29 +81,29 @@ func TestCreateClusterRoleBinding(t *testing.T) { } func TestGetClusterRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { - crb.Name = testName + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb.Name = test.TestName })).Build() - _, err := GetClusterRoleBinding(testName, testClient) + _, err := GetClusterRoleBinding(test.TestName, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetClusterRoleBinding(testName, testClient) + _, err = GetClusterRoleBinding(test.TestName, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListClusterRoleBindings(t *testing.T) { - crb1 := getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb1 := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { crb.Name = "crb-1" crb.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - crb2 := getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb2 := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { crb.Name = "crb-2" }) - crb3 := getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb3 := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { crb.Name = "crb-3" crb.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -151,14 +135,14 @@ func TestListClusterRoleBindings(t *testing.T) { } func TestUpdateClusterRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { - crb.Name = testName + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb.Name = test.TestName })).Build() - desiredClusterRoleBinding := getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { - crb.Name = testName - crb.RoleRef = testRoleRef - crb.Subjects = testSubjects + desiredClusterRoleBinding := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb.Name = test.TestName + crb.RoleRef = test.MakeTestRoleRef(test.TestName) + crb.Subjects = test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}) }) err := UpdateClusterRoleBinding(desiredClusterRoleBinding, testClient) @@ -166,33 +150,33 @@ func TestUpdateClusterRoleBinding(t *testing.T) { existingClusterRoleBinding := &rbacv1.ClusterRoleBinding{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, existingClusterRoleBinding) assert.NoError(t, err) assert.Equal(t, desiredClusterRoleBinding.Subjects, existingClusterRoleBinding.Subjects) testClient = fake.NewClientBuilder().Build() - existingClusterRoleBinding = getTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { - crb.Name = testName + existingClusterRoleBinding = test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb.Name = test.TestName }) err = UpdateClusterRoleBinding(existingClusterRoleBinding, testClient) assert.Error(t, err) } func TestDeleteClusterRoleBinding(t *testing.T) { - testClusterRoleBinding := getTestClusterRoleBinding(func(rb *rbacv1.ClusterRoleBinding) { - rb.Name = testName + testClusterRoleBinding := test.MakeTestClusterRoleBinding(func(rb *rbacv1.ClusterRoleBinding) { + rb.Name = test.TestName }) testClient := fake.NewClientBuilder().WithObjects(testClusterRoleBinding).Build() - err := DeleteClusterRoleBinding(testName, testClient) + err := DeleteClusterRoleBinding(test.TestName, testClient) assert.NoError(t, err) existingClusterRoleBinding := &rbacv1.ClusterRoleBinding{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Name: testName, + Name: test.TestName, }, existingClusterRoleBinding) assert.Error(t, err) diff --git a/pkg/permissions/permissions_test.go b/pkg/permissions/permissions_test.go index f3b920f57..039cc05c4 100644 --- a/pkg/permissions/permissions_test.go +++ b/pkg/permissions/permissions_test.go @@ -7,31 +7,11 @@ import ( cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/tests/test" ) // common test variables used across permissions tests var ( - testName = "test-name" - testInstance = "test-instance" - testInstanceNamespace = "test-instance-ns" - testNamespace = "test-ns" - testComponent = "test-component" - testKey = "test-key" - testVal = "test-value" - - testRules = []rbacv1.PolicyRule{ - { - APIGroups: []string{ - "", - }, - Resources: []string{ - "pods", - }, - Verbs: []string{ - "create", - }, - }, - } testRulesMutated = []rbacv1.PolicyRule{ { APIGroups: []string{ @@ -45,31 +25,12 @@ var ( }, }, } - testRoleRef = rbacv1.RoleRef{ - Kind: "Role", - Name: testName, - APIGroup: "rbac.authorization.k8s.io", - } - testSubjects = []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: testName, - Namespace: testNamespace, - }, - } - testKVP = map[string]string{ - testKey: testVal, - } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return errors.New("test-mutation-error") -} - func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *rbacv1.Role: - if obj.Namespace == testNamespace { + if obj.Namespace == test.TestNamespace { obj.Rules = testRulesMutated return nil } diff --git a/pkg/permissions/role_test.go b/pkg/permissions/role_test.go index 1e02c7dab..2508bdfe9 100644 --- a/pkg/permissions/role_test.go +++ b/pkg/permissions/role_test.go @@ -17,24 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type roleOpt func(*rbacv1.Role) - -func getTestRole(opts ...roleOpt) *rbacv1.Role { - desiredRole := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - - for _, opt := range opts { - opt(desiredRole) - } - return desiredRole -} - func TestRequestRole(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -46,22 +31,22 @@ func TestRequestRole(t *testing.T) { wantErr bool }{ { - name: "request role, no mutation, custom name, labels, annotations", + name: "request role", rolReq: RoleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Rules: testRules, + Rules: test.TestRules, }, - desiredRole: getTestRole(func(r *rbacv1.Role) { - r.Name = testName - r.Namespace = testNamespace - r.Labels = testKVP - r.Annotations = testKVP - r.Rules = testRules + desiredRole: test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName + r.Namespace = test.TestNamespace + r.Labels = test.TestKVP + r.Annotations = test.TestKVP + r.Rules = test.TestRules }), wantErr: false, }, @@ -69,22 +54,22 @@ func TestRequestRole(t *testing.T) { name: "request role, successful mutation", rolReq: RoleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Rules: testRules, + Rules: test.TestRules, Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, - desiredRole: getTestRole(func(r *rbacv1.Role) { - r.Name = testName - r.Namespace = testNamespace - r.Labels = testKVP - r.Annotations = testKVP + desiredRole: test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName + r.Namespace = test.TestNamespace + r.Labels = test.TestKVP + r.Annotations = test.TestKVP r.Rules = testRulesMutated }), wantErr: false, @@ -93,22 +78,22 @@ func TestRequestRole(t *testing.T) { name: "request role, failed mutation", rolReq: RoleRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Rules: testRules, + Rules: test.TestRules, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredRole: getTestRole(func(r *rbacv1.Role) { - r.Name = testName - r.Namespace = testNamespace - r.Labels = testKVP - r.Annotations = testKVP + desiredRole: test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName + r.Namespace = test.TestNamespace + r.Labels = test.TestKVP + r.Annotations = test.TestKVP r.Rules = testRulesMutated }), @@ -135,23 +120,23 @@ func TestRequestRole(t *testing.T) { func TestCreateRole(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredRole := getTestRole(func(r *rbacv1.Role) { + desiredRole := test.MakeTestRole(func(r *rbacv1.Role) { r.TypeMeta = metav1.TypeMeta{ Kind: "Role", APIVersion: "rbac.authorization.k8s.io/v1", } - r.Name = testName - r.Namespace = testNamespace - r.Labels = testKVP - r.Annotations = testKVP + r.Name = test.TestName + r.Namespace = test.TestNamespace + r.Labels = test.TestKVP + r.Annotations = test.TestKVP }) err := CreateRole(desiredRole, testClient) assert.NoError(t, err) createdRole := &rbacv1.Role{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdRole) assert.NoError(t, err) @@ -159,35 +144,35 @@ func TestCreateRole(t *testing.T) { } func TestGetRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestRole(func(r *rbacv1.Role) { - r.Name = testName - r.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName + r.Namespace = test.TestNamespace })).Build() - _, err := GetRole(testName, testNamespace, testClient) + _, err := GetRole(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetRole(testName, testNamespace, testClient) + _, err = GetRole(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListRoles(t *testing.T) { - role1 := getTestRole(func(r *rbacv1.Role) { + role1 := test.MakeTestRole(func(r *rbacv1.Role) { r.Name = "role-1" r.Labels[common.AppK8sKeyComponent] = "new-component-1" - r.Namespace = testNamespace + r.Namespace = test.TestNamespace }) - role2 := getTestRole(func(r *rbacv1.Role) { + role2 := test.MakeTestRole(func(r *rbacv1.Role) { r.Name = "role-2" - r.Namespace = testNamespace + r.Namespace = test.TestNamespace }) - role3 := getTestRole(func(r *rbacv1.Role) { + role3 := test.MakeTestRole(func(r *rbacv1.Role) { r.Name = "role-3" r.Labels[common.AppK8sKeyComponent] = "new-component-2" - r.Namespace = testNamespace + r.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -204,7 +189,7 @@ func TestListRoles(t *testing.T) { desiredRoles := []string{"role-1", "role-3"} - existingRoleList, err := ListRoles(testNamespace, testClient, listOpts) + existingRoleList, err := ListRoles(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingRoles := []string{} @@ -218,51 +203,51 @@ func TestListRoles(t *testing.T) { } func TestUpdateRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestRole(func(r *rbacv1.Role) { - r.Name = testName - r.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName + r.Namespace = test.TestNamespace })).Build() - desiredRole := getTestRole(func(r *rbacv1.Role) { - r.Name = testName + desiredRole := test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName r.Rules = testRulesMutated - r.Namespace = testNamespace + r.Namespace = test.TestNamespace }) err := UpdateRole(desiredRole, testClient) assert.NoError(t, err) existingRole := &rbacv1.Role{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingRole) assert.NoError(t, err) assert.Equal(t, desiredRole.Rules, existingRole.Rules) testClient = fake.NewClientBuilder().Build() - existingRole = getTestRole(func(r *rbacv1.Role) { - r.Name = testName + existingRole = test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName }) err = UpdateRole(existingRole, testClient) assert.Error(t, err) } func TestDeleteRole(t *testing.T) { - testRole := getTestRole(func(r *rbacv1.Role) { - r.Name = testName - r.Namespace = testNamespace + testRole := test.MakeTestRole(func(r *rbacv1.Role) { + r.Name = test.TestName + r.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testRole).Build() - err := DeleteRole(testName, testNamespace, testClient) + err := DeleteRole(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingRole := &rbacv1.Role{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingRole) assert.Error(t, err) diff --git a/pkg/permissions/rolebinding_test.go b/pkg/permissions/rolebinding_test.go index e1cd53428..a1145d8c7 100644 --- a/pkg/permissions/rolebinding_test.go +++ b/pkg/permissions/rolebinding_test.go @@ -17,24 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type roleBindingOpt func(*rbacv1.RoleBinding) - -func getTestRoleBinding(opts ...roleBindingOpt) *rbacv1.RoleBinding { - desiredRoleBinding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - - for _, opt := range opts { - opt(desiredRoleBinding) - } - return desiredRoleBinding -} - func TestRequestRoleBinding(t *testing.T) { tests := []struct { name string @@ -45,42 +30,42 @@ func TestRequestRoleBinding(t *testing.T) { name: "request rolebinding", rbReq: RoleBindingRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - RoleRef: testRoleRef, - Subjects: testSubjects, + RoleRef: test.MakeTestRoleRef(test.TestName), + Subjects: test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}), }, - desiredRb: getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName - rb.Namespace = testNamespace - rb.Labels = testKVP - rb.Annotations = testKVP - rb.RoleRef = testRoleRef - rb.Subjects = testSubjects + desiredRb: test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName + rb.Namespace = test.TestNamespace + rb.Labels = test.TestKVP + rb.Annotations = test.TestKVP + rb.RoleRef = test.MakeTestRoleRef(test.TestName) + rb.Subjects = test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}) }), }, { name: "request rolebinding, custom name, labels, annotations", rbReq: RoleBindingRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - RoleRef: testRoleRef, - Subjects: testSubjects, + RoleRef: test.MakeTestRoleRef(test.TestName), + Subjects: test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}), }, - desiredRb: getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName - rb.Namespace = testNamespace - rb.Labels = util.MergeMaps(rb.Labels, testKVP) - rb.Annotations = util.MergeMaps(rb.Annotations, testKVP) - rb.RoleRef = testRoleRef - rb.Subjects = testSubjects + desiredRb: test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName + rb.Namespace = test.TestNamespace + rb.Labels = util.MergeMaps(rb.Labels, test.TestKVP) + rb.Annotations = util.MergeMaps(rb.Annotations, test.TestKVP) + rb.RoleRef = test.MakeTestRoleRef(test.TestName) + rb.Subjects = test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}) }), }, } @@ -98,23 +83,23 @@ func TestRequestRoleBinding(t *testing.T) { func TestCreateRoleBinding(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredRoleBinding := getTestRoleBinding(func(rb *rbacv1.RoleBinding) { + desiredRoleBinding := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { rb.TypeMeta = metav1.TypeMeta{ Kind: "RoleBinding", APIVersion: "rbac.authorization.k8s.io/v1", } - rb.Name = testName - rb.Namespace = testNamespace - rb.Labels = testKVP - rb.Annotations = testKVP + rb.Name = test.TestName + rb.Namespace = test.TestNamespace + rb.Labels = test.TestKVP + rb.Annotations = test.TestKVP }) err := CreateRoleBinding(desiredRoleBinding, testClient) assert.NoError(t, err) createdRoleBinding := &rbacv1.RoleBinding{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdRoleBinding) assert.NoError(t, err) @@ -122,35 +107,35 @@ func TestCreateRoleBinding(t *testing.T) { } func TestGetRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName - rb.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName + rb.Namespace = test.TestNamespace })).Build() - _, err := GetRoleBinding(testName, testNamespace, testClient) + _, err := GetRoleBinding(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetRoleBinding(testName, testNamespace, testClient) + _, err = GetRoleBinding(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListRoleBindings(t *testing.T) { - rb1 := getTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb1 := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { rb.Name = "rb-1" rb.Labels[common.AppK8sKeyComponent] = "new-component-1" - rb.Namespace = testNamespace + rb.Namespace = test.TestNamespace }) - rb2 := getTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb2 := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { rb.Name = "rb-2" - rb.Namespace = testNamespace + rb.Namespace = test.TestNamespace }) - rb3 := getTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb3 := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { rb.Name = "rb-3" rb.Labels[common.AppK8sKeyComponent] = "new-component-2" - rb.Namespace = testNamespace + rb.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -167,7 +152,7 @@ func TestListRoleBindings(t *testing.T) { desiredRoleBindings := []string{"rb-1", "rb-3"} - existingRoleBindingList, err := ListRoleBindings(testNamespace, testClient, listOpts) + existingRoleBindingList, err := ListRoleBindings(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingRoleBindings := []string{} @@ -180,13 +165,13 @@ func TestListRoleBindings(t *testing.T) { } func TestUpdateRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName - rb.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName + rb.Namespace = test.TestNamespace })).Build() - desiredRoleBinding := getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName + desiredRoleBinding := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName rb.RoleRef = rbacv1.RoleRef{ Kind: "Role", Name: "desired-role-name", @@ -196,10 +181,10 @@ func TestUpdateRoleBinding(t *testing.T) { { Kind: "ServiceAccount", Name: "new-sa", - Namespace: testNamespace, + Namespace: test.TestNamespace, }, } - rb.Namespace = testNamespace + rb.Namespace = test.TestNamespace }) @@ -208,8 +193,8 @@ func TestUpdateRoleBinding(t *testing.T) { existingRoleBinding := &rbacv1.RoleBinding{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingRoleBinding) assert.NoError(t, err) @@ -217,28 +202,28 @@ func TestUpdateRoleBinding(t *testing.T) { assert.Equal(t, desiredRoleBinding.Subjects, existingRoleBinding.Subjects) testClient = fake.NewClientBuilder().Build() - existingRoleBinding = getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName + existingRoleBinding = test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName }) err = UpdateRoleBinding(existingRoleBinding, testClient) assert.Error(t, err) } func TestDeleteRoleBinding(t *testing.T) { - testRoleBinding := getTestRoleBinding(func(rb *rbacv1.RoleBinding) { - rb.Name = testName - rb.Namespace = testNamespace + testRoleBinding := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb.Name = test.TestName + rb.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testRoleBinding).Build() - err := DeleteRoleBinding(testName, testNamespace, testClient) + err := DeleteRoleBinding(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingRoleBinding := &rbacv1.RoleBinding{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingRoleBinding) assert.Error(t, err) diff --git a/pkg/permissions/serviceaccount_test.go b/pkg/permissions/serviceaccount_test.go index b36b74f61..f2b3cd9c6 100644 --- a/pkg/permissions/serviceaccount_test.go +++ b/pkg/permissions/serviceaccount_test.go @@ -17,25 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type serviceAccountOpt func(*corev1.ServiceAccount) - -func getTestServiceAccount(opts ...serviceAccountOpt) *corev1.ServiceAccount { - desiredServiceAccount := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - - for _, opt := range opts { - opt(desiredServiceAccount) - } - - return desiredServiceAccount -} - func TestRequestServiceAccount(t *testing.T) { tests := []struct { name string @@ -43,20 +27,20 @@ func TestRequestServiceAccount(t *testing.T) { desiredSa *corev1.ServiceAccount }{ { - name: "request service account, custom name, labels, annotations", + name: "request service account", saReq: ServiceAccountRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, }, - desiredSa: getTestServiceAccount(func(sa *corev1.ServiceAccount) { - sa.Name = testName - sa.Namespace = testNamespace - sa.Labels = util.MergeMaps(sa.Labels, testKVP) - sa.Annotations = util.MergeMaps(sa.Annotations, testKVP) + desiredSa: test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = test.TestName + sa.Namespace = test.TestNamespace + sa.Labels = util.MergeMaps(sa.Labels, test.TestKVP) + sa.Annotations = util.MergeMaps(sa.Annotations, test.TestKVP) }), }, } @@ -72,23 +56,23 @@ func TestRequestServiceAccount(t *testing.T) { func TestCreateServiceAccount(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredServiceAccount := getTestServiceAccount(func(sa *corev1.ServiceAccount) { + desiredServiceAccount := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { sa.TypeMeta = metav1.TypeMeta{ Kind: "ServiceAccount", APIVersion: "v1", } - sa.Name = testName - sa.Namespace = testNamespace - sa.Labels = testKVP - sa.Annotations = testKVP + sa.Name = test.TestName + sa.Namespace = test.TestNamespace + sa.Labels = test.TestKVP + sa.Annotations = test.TestKVP }) err := CreateServiceAccount(desiredServiceAccount, testClient) assert.NoError(t, err) createdServiceAccount := &corev1.ServiceAccount{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdServiceAccount) assert.NoError(t, err) @@ -96,35 +80,35 @@ func TestCreateServiceAccount(t *testing.T) { } func TestGetServiceAccount(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestServiceAccount(func(sa *corev1.ServiceAccount) { - sa.Name = testName - sa.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = test.TestName + sa.Namespace = test.TestNamespace })).Build() - _, err := GetServiceAccount(testName, testNamespace, testClient) + _, err := GetServiceAccount(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetServiceAccount(testName, testNamespace, testClient) + _, err = GetServiceAccount(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListServiceAccounts(t *testing.T) { - sa1 := getTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa1 := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { sa.Name = "sa-1" sa.Labels[common.AppK8sKeyComponent] = "new-component-1" - sa.Namespace = testNamespace + sa.Namespace = test.TestNamespace }) - sa2 := getTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa2 := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { sa.Name = "sa-2" - sa.Namespace = testNamespace + sa.Namespace = test.TestNamespace }) - sa3 := getTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa3 := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { sa.Name = "sa-3" sa.Labels[common.AppK8sKeyComponent] = "new-component-2" - sa.Namespace = testNamespace + sa.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -141,7 +125,7 @@ func TestListServiceAccounts(t *testing.T) { desiredServiceAccounts := []string{"sa-1", "sa-3"} - existingServiceAccountList, err := ListServiceAccounts(testNamespace, testClient, listOpts) + existingServiceAccountList, err := ListServiceAccounts(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingServiceAccounts := []string{} @@ -154,19 +138,19 @@ func TestListServiceAccounts(t *testing.T) { } func TestUpdateServiceAccount(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestServiceAccount(func(sa *corev1.ServiceAccount) { - sa.Name = testName - sa.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = test.TestName + sa.Namespace = test.TestNamespace })).Build() - desiredServiceAccount := getTestServiceAccount(func(sa *corev1.ServiceAccount) { - sa.Name = testName + desiredServiceAccount := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = test.TestName sa.ImagePullSecrets = []corev1.LocalObjectReference{ { Name: "new-secret", }, } - sa.Namespace = testNamespace + sa.Namespace = test.TestNamespace }) err := UpdateServiceAccount(desiredServiceAccount, testClient) @@ -174,8 +158,8 @@ func TestUpdateServiceAccount(t *testing.T) { existingServiceAccount := &corev1.ServiceAccount{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingServiceAccount) assert.NoError(t, err) @@ -183,28 +167,28 @@ func TestUpdateServiceAccount(t *testing.T) { assert.Equal(t, desiredServiceAccount.AutomountServiceAccountToken, existingServiceAccount.AutomountServiceAccountToken) testClient = fake.NewClientBuilder().Build() - existingServiceAccount = getTestServiceAccount(func(sa *corev1.ServiceAccount) { - sa.Name = testName + existingServiceAccount = test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = test.TestName }) err = UpdateServiceAccount(existingServiceAccount, testClient) assert.Error(t, err) } func TestDeleteServiceAccount(t *testing.T) { - testServiceAccount := getTestServiceAccount(func(sa *corev1.ServiceAccount) { - sa.Name = testName - sa.Namespace = testNamespace + testServiceAccount := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { + sa.Name = test.TestName + sa.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testServiceAccount).Build() - err := DeleteServiceAccount(testName, testNamespace, testClient) + err := DeleteServiceAccount(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingServiceAccount := &corev1.ServiceAccount{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingServiceAccount) assert.Error(t, err) diff --git a/pkg/workloads/configmap_test.go b/pkg/workloads/configmap_test.go index e757cf6e1..110c46d55 100644 --- a/pkg/workloads/configmap_test.go +++ b/pkg/workloads/configmap_test.go @@ -17,100 +17,84 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type configMapOpt func(*corev1.ConfigMap) - -func getTestConfigMap(opts ...configMapOpt) *corev1.ConfigMap { - desiredConfigMap := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Data: make(map[string]string), - } - - for _, opt := range opts { - opt(desiredConfigMap) - } - return desiredConfigMap -} - func TestRequestConfigMap(t *testing.T) { testClient := fake.NewClientBuilder().Build() tests := []struct { name string - deployReq ConfigMapRequest + cmReq ConfigMapRequest desiredConfigMap *corev1.ConfigMap wantErr bool }{ { - name: "request configMap, no mutation, custom name, labels, annotations", - deployReq: ConfigMapRequest{ + name: "request configMap", + cmReq: ConfigMapRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Data: testKVP, + Data: test.TestKVP, }, - desiredConfigMap: getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testName - cm.Namespace = testNamespace - cm.Labels = testKVP - cm.Annotations = testKVP - cm.Data = testKVP + desiredConfigMap: test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestName + cm.Namespace = test.TestNamespace + cm.Labels = test.TestKVP + cm.Annotations = test.TestKVP + cm.Data = test.TestKVP }), wantErr: false, }, { name: "request configMap, successful mutation", - deployReq: ConfigMapRequest{ + cmReq: ConfigMapRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Data: testKVP, + Data: test.TestKVP, Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, - desiredConfigMap: getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testNameMutated - cm.Namespace = testNamespace - cm.Labels = testKVP - cm.Annotations = testKVP - cm.Data = testKVPMutated + desiredConfigMap: test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestNameMutated + cm.Namespace = test.TestNamespace + cm.Labels = test.TestKVP + cm.Annotations = test.TestKVP + cm.Data = test.TestKVPMutated }), wantErr: false, }, { name: "request configMap, failed mutation", - deployReq: ConfigMapRequest{ + cmReq: ConfigMapRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - Data: testKVP, + Data: test.TestKVP, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredConfigMap: getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testName - cm.Namespace = testNamespace - cm.Labels = testKVP - cm.Annotations = testKVP - cm.Data = testKVP + desiredConfigMap: test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestName + cm.Namespace = test.TestNamespace + cm.Labels = test.TestKVP + cm.Annotations = test.TestKVP + cm.Data = test.TestKVP }), wantErr: true, }, @@ -118,7 +102,7 @@ func TestRequestConfigMap(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - gotConfigMap, err := RequestConfigMap(test.deployReq) + gotConfigMap, err := RequestConfigMap(test.cmReq) if !test.wantErr { assert.NoError(t, err) @@ -135,24 +119,24 @@ func TestRequestConfigMap(t *testing.T) { func TestCreateConfigMap(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredConfigMap := getTestConfigMap(func(cm *corev1.ConfigMap) { + desiredConfigMap := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { cm.TypeMeta = metav1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", } - cm.Name = testName - cm.Namespace = testNamespace - cm.Labels = testKVP - cm.Annotations = testKVP - cm.Data = testKVP + cm.Name = test.TestName + cm.Namespace = test.TestNamespace + cm.Labels = test.TestKVP + cm.Annotations = test.TestKVP + cm.Data = test.TestKVP }) err := CreateConfigMap(desiredConfigMap, testClient) assert.NoError(t, err) createdConfigMap := &corev1.ConfigMap{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdConfigMap) assert.NoError(t, err) @@ -160,40 +144,40 @@ func TestCreateConfigMap(t *testing.T) { } func TestGetConfigMap(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testName - cm.Namespace = testNamespace - cm.Data = testKVP + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestName + cm.Namespace = test.TestNamespace + cm.Data = test.TestKVP })).Build() - _, err := GetConfigMap(testName, testNamespace, testClient) + _, err := GetConfigMap(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetConfigMap(testName, testNamespace, testClient) + _, err = GetConfigMap(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListConfigMaps(t *testing.T) { - configMap1 := getTestConfigMap(func(cm *corev1.ConfigMap) { + configMap1 := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { cm.Name = "configMap-1" - cm.Namespace = testNamespace + cm.Namespace = test.TestNamespace cm.Labels[common.AppK8sKeyComponent] = "new-component-1" - cm.Data = testKVP + cm.Data = test.TestKVP }) - configMap2 := getTestConfigMap(func(cm *corev1.ConfigMap) { + configMap2 := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { cm.Name = "configMap-2" - cm.Namespace = testNamespace + cm.Namespace = test.TestNamespace }) - configMap3 := getTestConfigMap(func(cm *corev1.ConfigMap) { + configMap3 := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { cm.Name = "configMap-3" cm.Labels[common.AppK8sKeyComponent] = "new-component-2" - cm.Data = testKVP - cm.Namespace = testNamespace + cm.Data = test.TestKVP + cm.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -210,7 +194,7 @@ func TestListConfigMaps(t *testing.T) { desiredConfigMaps := []string{"configMap-1", "configMap-3"} - existingConfigMapList, err := ListConfigMaps(testNamespace, testClient, listOpts) + existingConfigMapList, err := ListConfigMaps(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingConfigMaps := []string{} @@ -223,15 +207,15 @@ func TestListConfigMaps(t *testing.T) { } func TestUpdateConfigMap(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testName - cm.Namespace = testNamespace - cm.Data = testKVP + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestName + cm.Namespace = test.TestNamespace + cm.Data = test.TestKVP })).Build() - desiredConfigMap := getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testName - cm.Namespace = testNamespace + desiredConfigMap := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestName + cm.Namespace = test.TestNamespace cm.Data = map[string]string{ "application.instanceLabelKey": "mycompany.com/appname", "admin.enabled": "true", @@ -242,17 +226,17 @@ func TestUpdateConfigMap(t *testing.T) { existingConfigMap := &corev1.ConfigMap{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingConfigMap) assert.NoError(t, err) assert.Equal(t, desiredConfigMap.Data, existingConfigMap.Data) testClient = fake.NewClientBuilder().Build() - existingConfigMap = getTestConfigMap(func(cm *corev1.ConfigMap) { - cm.Name = testName - cm.Namespace = testNamespace + existingConfigMap = test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + cm.Name = test.TestName + cm.Namespace = test.TestNamespace cm.Data = nil }) err = UpdateConfigMap(existingConfigMap, testClient) @@ -260,20 +244,20 @@ func TestUpdateConfigMap(t *testing.T) { } func TestDeleteConfigMap(t *testing.T) { - testConfigMap := getTestConfigMap(func(configMap *corev1.ConfigMap) { - configMap.Name = testName - configMap.Namespace = testNamespace + testConfigMap := test.MakeTestConfigMap(func(configMap *corev1.ConfigMap) { + configMap.Name = test.TestName + configMap.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testConfigMap).Build() - err := DeleteConfigMap(testName, testNamespace, testClient) + err := DeleteConfigMap(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingConfigMap := &corev1.ConfigMap{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingConfigMap) assert.Error(t, err) diff --git a/pkg/workloads/deployment_test.go b/pkg/workloads/deployment_test.go index 9ea25bc46..22a0c42e0 100644 --- a/pkg/workloads/deployment_test.go +++ b/pkg/workloads/deployment_test.go @@ -17,27 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type deploymentOpt func(*appsv1.Deployment) - -func getTestDeployment(opts ...deploymentOpt) *appsv1.Deployment { - desiredDeployment := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{}, - }, - } - - for _, opt := range opts { - opt(desiredDeployment) - } - return desiredDeployment -} - func TestRequestDeployment(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -49,26 +31,26 @@ func TestRequestDeployment(t *testing.T) { wantErr bool }{ { - name: "request deployment, no mutation, custom name, labels, annotations", + name: "request deployment", deployReq: DeploymentRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: appsv1.DeploymentSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: testKVP, + MatchLabels: test.TestKVP, }, }, }, - desiredDeployment: getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testName - d.Namespace = testNamespace - d.Labels = testKVP - d.Annotations = testKVP - d.Spec.Selector.MatchLabels = testKVP + desiredDeployment: test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestName + d.Namespace = test.TestNamespace + d.Labels = test.TestKVP + d.Annotations = test.TestKVP + d.Spec.Selector.MatchLabels = test.TestKVP }), wantErr: false, }, @@ -76,14 +58,14 @@ func TestRequestDeployment(t *testing.T) { name: "request deployment, successful mutation", deployReq: DeploymentRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: appsv1.DeploymentSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: testKVP, + MatchLabels: test.TestKVP, }, }, Mutations: []mutation.MutateFunc{ @@ -91,12 +73,12 @@ func TestRequestDeployment(t *testing.T) { }, Client: testClient, }, - desiredDeployment: getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testNameMutated - d.Namespace = testNamespace - d.Labels = testKVP - d.Annotations = testKVP - d.Spec.Selector.MatchLabels = testKVP + desiredDeployment: test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestNameMutated + d.Namespace = test.TestNamespace + d.Labels = test.TestKVP + d.Annotations = test.TestKVP + d.Spec.Selector.MatchLabels = test.TestKVP d.Spec.Replicas = &testReplicasMutated }), wantErr: false, @@ -105,27 +87,27 @@ func TestRequestDeployment(t *testing.T) { name: "request deployment, failed mutation", deployReq: DeploymentRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: appsv1.DeploymentSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: testKVP, + MatchLabels: test.TestKVP, }, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredDeployment: getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testNameMutated - d.Namespace = testNamespace - d.Labels = testKVP - d.Annotations = testKVP - d.Spec.Selector.MatchLabels = testKVP + desiredDeployment: test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestNameMutated + d.Namespace = test.TestNamespace + d.Labels = test.TestKVP + d.Annotations = test.TestKVP + d.Spec.Selector.MatchLabels = test.TestKVP }), wantErr: true, }, @@ -150,23 +132,23 @@ func TestRequestDeployment(t *testing.T) { func TestCreateDeployment(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredDeployment := getTestDeployment(func(d *appsv1.Deployment) { + desiredDeployment := test.MakeTestDeployment(func(d *appsv1.Deployment) { d.TypeMeta = metav1.TypeMeta{ Kind: "Deployment", APIVersion: "apps/v1", } - d.Name = testName - d.Namespace = testNamespace - d.Labels = testKVP - d.Annotations = testKVP + d.Name = test.TestName + d.Namespace = test.TestNamespace + d.Labels = test.TestKVP + d.Annotations = test.TestKVP }) err := CreateDeployment(desiredDeployment, testClient) assert.NoError(t, err) createdDeployment := &appsv1.Deployment{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdDeployment) assert.NoError(t, err) @@ -174,38 +156,38 @@ func TestCreateDeployment(t *testing.T) { } func TestGetDeployment(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testName - d.Namespace = testNamespace - d.Labels = testKVP - d.Annotations = testKVP + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestName + d.Namespace = test.TestNamespace + d.Labels = test.TestKVP + d.Annotations = test.TestKVP })).Build() - _, err := GetDeployment(testName, testNamespace, testClient) + _, err := GetDeployment(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetDeployment(testName, testNamespace, testClient) + _, err = GetDeployment(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListDeployments(t *testing.T) { - deployment1 := getTestDeployment(func(d *appsv1.Deployment) { + deployment1 := test.MakeTestDeployment(func(d *appsv1.Deployment) { d.Name = "deployment-1" - d.Namespace = testNamespace + d.Namespace = test.TestNamespace d.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - deployment2 := getTestDeployment(func(d *appsv1.Deployment) { + deployment2 := test.MakeTestDeployment(func(d *appsv1.Deployment) { d.Name = "deployment-2" - d.Namespace = testNamespace + d.Namespace = test.TestNamespace }) - deployment3 := getTestDeployment(func(d *appsv1.Deployment) { + deployment3 := test.MakeTestDeployment(func(d *appsv1.Deployment) { d.Name = "deployment-3" d.Labels[common.AppK8sKeyComponent] = "new-component-2" - d.Namespace = testNamespace + d.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -222,7 +204,7 @@ func TestListDeployments(t *testing.T) { desiredDeployments := []string{"deployment-1", "deployment-3"} - existingDeploymentList, err := ListDeployments(testNamespace, testClient, listOpts) + existingDeploymentList, err := ListDeployments(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingDeployments := []string{} @@ -235,14 +217,14 @@ func TestListDeployments(t *testing.T) { } func TestUpdateDeployment(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testName - d.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestName + d.Namespace = test.TestNamespace })).Build() - desiredDeployment := getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testName - d.Namespace = testNamespace + desiredDeployment := test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestName + d.Namespace = test.TestNamespace d.Labels = map[string]string{ "control-plane": "argocd-operator", } @@ -252,37 +234,37 @@ func TestUpdateDeployment(t *testing.T) { existingDeployment := &appsv1.Deployment{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingDeployment) assert.NoError(t, err) assert.Equal(t, desiredDeployment.Labels, existingDeployment.Labels) testClient = fake.NewClientBuilder().Build() - existingDeployment = getTestDeployment(func(d *appsv1.Deployment) { - d.Name = testName - d.Namespace = testNamespace + existingDeployment = test.MakeTestDeployment(func(d *appsv1.Deployment) { + d.Name = test.TestName + d.Namespace = test.TestNamespace }) err = UpdateDeployment(existingDeployment, testClient) assert.Error(t, err) } func TestDeleteDeployment(t *testing.T) { - testDeployment := getTestDeployment(func(deployment *appsv1.Deployment) { - deployment.Name = testName - deployment.Namespace = testNamespace + testDeployment := test.MakeTestDeployment(func(deployment *appsv1.Deployment) { + deployment.Name = test.TestName + deployment.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testDeployment).Build() - err := DeleteDeployment(testName, testNamespace, testClient) + err := DeleteDeployment(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingDeployment := &appsv1.Deployment{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingDeployment) assert.Error(t, err) diff --git a/pkg/workloads/hpa_test.go b/pkg/workloads/hpa_test.go index f4e21e12d..e32e421a5 100644 --- a/pkg/workloads/hpa_test.go +++ b/pkg/workloads/hpa_test.go @@ -17,25 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type horizontalPodAutoscalerOpt func(*autoscaling.HorizontalPodAutoscaler) - -func getTestHorizontalPodAutoscaler(opts ...horizontalPodAutoscalerOpt) *autoscaling.HorizontalPodAutoscaler { - desiredHorizontalPodAutoscaler := &autoscaling.HorizontalPodAutoscaler{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: autoscaling.HorizontalPodAutoscalerSpec{}, - } - - for _, opt := range opts { - opt(desiredHorizontalPodAutoscaler) - } - return desiredHorizontalPodAutoscaler -} - func TestRequestHorizontalPodAutoscaler(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -47,23 +31,23 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { wantErr bool }{ { - name: "request horizontalPodAutoscaler, no mutation, custom name, labels, annotations", + name: "request horizontalPodAutoscaler", hpaReq: HorizontalPodAutoscalerRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: autoscaling.HorizontalPodAutoscalerSpec{ MaxReplicas: testReplicasMutated, }, }, - desiredHorizontalPodAutoscaler: getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace - hpa.Labels = testKVP - hpa.Annotations = testKVP + desiredHorizontalPodAutoscaler: test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace + hpa.Labels = test.TestKVP + hpa.Annotations = test.TestKVP hpa.Spec.MaxReplicas = testReplicasMutated }), wantErr: false, @@ -72,10 +56,10 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { name: "request horizontalPodAutoscaler, successful mutation", hpaReq: HorizontalPodAutoscalerRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: autoscaling.HorizontalPodAutoscalerSpec{ MaxReplicas: testReplicasMutated, @@ -85,11 +69,11 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { }, Client: testClient, }, - desiredHorizontalPodAutoscaler: getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testNameMutated - hpa.Namespace = testNamespace - hpa.Labels = testKVP - hpa.Annotations = testKVP + desiredHorizontalPodAutoscaler: test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestNameMutated + hpa.Namespace = test.TestNamespace + hpa.Labels = test.TestKVP + hpa.Annotations = test.TestKVP hpa.Spec.MaxReplicas = testReplicasMutated }), wantErr: false, @@ -98,24 +82,24 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { name: "request horizontalPodAutoscaler, failed mutation", hpaReq: HorizontalPodAutoscalerRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: autoscaling.HorizontalPodAutoscalerSpec{ MaxReplicas: testReplicasMutated, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredHorizontalPodAutoscaler: getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace - hpa.Labels = testKVP - hpa.Annotations = testKVP + desiredHorizontalPodAutoscaler: test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace + hpa.Labels = test.TestKVP + hpa.Annotations = test.TestKVP hpa.Spec.MaxReplicas = testReplicasMutated }), wantErr: true, @@ -141,23 +125,23 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { func TestCreateHorizontalPodAutoscaler(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredHorizontalPodAutoscaler := getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { + desiredHorizontalPodAutoscaler := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.TypeMeta = metav1.TypeMeta{ Kind: "HorizontalPodAutoscaler", APIVersion: "autoscaling/v1", } - hpa.Name = testName - hpa.Namespace = testNamespace - hpa.Labels = testKVP - hpa.Annotations = testKVP + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace + hpa.Labels = test.TestKVP + hpa.Annotations = test.TestKVP }) err := CreateHorizontalPodAutoscaler(desiredHorizontalPodAutoscaler, testClient) assert.NoError(t, err) createdHorizontalPodAutoscaler := &autoscaling.HorizontalPodAutoscaler{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdHorizontalPodAutoscaler) assert.NoError(t, err) @@ -165,35 +149,35 @@ func TestCreateHorizontalPodAutoscaler(t *testing.T) { } func TestGetHorizontalPodAutoscaler(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace })).Build() - _, err := GetHorizontalPodAutoscaler(testName, testNamespace, testClient) + _, err := GetHorizontalPodAutoscaler(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetHorizontalPodAutoscaler(testName, testNamespace, testClient) + _, err = GetHorizontalPodAutoscaler(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListHorizontalPodAutoscalers(t *testing.T) { - horizontalPodAutoscaler1 := getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { + horizontalPodAutoscaler1 := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = "horizontalPodAutoscaler-1" - hpa.Namespace = testNamespace + hpa.Namespace = test.TestNamespace hpa.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - horizontalPodAutoscaler2 := getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { + horizontalPodAutoscaler2 := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = "horizontalPodAutoscaler-2" - hpa.Namespace = testNamespace + hpa.Namespace = test.TestNamespace }) - horizontalPodAutoscaler3 := getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { + horizontalPodAutoscaler3 := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = "horizontalPodAutoscaler-3" hpa.Labels[common.AppK8sKeyComponent] = "new-component-2" - hpa.Namespace = testNamespace + hpa.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -210,7 +194,7 @@ func TestListHorizontalPodAutoscalers(t *testing.T) { desiredHorizontalPodAutoscalers := []string{"horizontalPodAutoscaler-1", "horizontalPodAutoscaler-3"} - existingHorizontalPodAutoscalerList, err := ListHorizontalPodAutoscalers(testNamespace, testClient, listOpts) + existingHorizontalPodAutoscalerList, err := ListHorizontalPodAutoscalers(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingHorizontalPodAutoscalers := []string{} @@ -227,14 +211,14 @@ func TestUpdateHorizontalPodAutoscaler(t *testing.T) { maxReplicas int32 = 3 minReplicas int32 = 1 ) - testClient := fake.NewClientBuilder().WithObjects(getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace })).Build() - desiredHorizontalPodAutoscaler := getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace + desiredHorizontalPodAutoscaler := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace hpa.Spec.MinReplicas = &minReplicas hpa.Spec.MaxReplicas = maxReplicas }) @@ -243,37 +227,37 @@ func TestUpdateHorizontalPodAutoscaler(t *testing.T) { existingHorizontalPodAutoscaler := &autoscaling.HorizontalPodAutoscaler{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingHorizontalPodAutoscaler) assert.NoError(t, err) assert.Equal(t, desiredHorizontalPodAutoscaler.Spec, existingHorizontalPodAutoscaler.Spec) testClient = fake.NewClientBuilder().Build() - existingHorizontalPodAutoscaler = getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace + existingHorizontalPodAutoscaler = test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace }) err = UpdateHorizontalPodAutoscaler(existingHorizontalPodAutoscaler, testClient) assert.Error(t, err) } func TestDeleteHorizontalPodAutoscaler(t *testing.T) { - testHPA := getTestHorizontalPodAutoscaler(func(hpa *autoscaling.HorizontalPodAutoscaler) { - hpa.Name = testName - hpa.Namespace = testNamespace + testHPA := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + hpa.Name = test.TestName + hpa.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testHPA).Build() - err := DeleteHorizontalPodAutoscaler(testName, testNamespace, testClient) + err := DeleteHorizontalPodAutoscaler(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingHPA := &autoscaling.HorizontalPodAutoscaler{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingHPA) assert.Error(t, err) diff --git a/pkg/workloads/secret_test.go b/pkg/workloads/secret_test.go index b1ebfd0fc..ea2080996 100644 --- a/pkg/workloads/secret_test.go +++ b/pkg/workloads/secret_test.go @@ -17,25 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type secretOpt func(*corev1.Secret) - -func getTestSecret(opts ...secretOpt) *corev1.Secret { - desiredSecret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - StringData: map[string]string{}, - } - - for _, opt := range opts { - opt(desiredSecret) - } - return desiredSecret -} - func TestRequestSecret(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -47,23 +31,23 @@ func TestRequestSecret(t *testing.T) { wantErr bool }{ { - name: "request secret, no mutation, custom name, labels, annotations", + name: "request secret", deployReq: SecretRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - StringData: testKVP, + StringData: test.TestKVP, Type: corev1.SecretTypeBasicAuth, }, - desiredSecret: getTestSecret(func(s *corev1.Secret) { - s.Name = testName - s.Namespace = testNamespace - s.Labels = testKVP - s.Annotations = testKVP - s.StringData = testKVP + desiredSecret: test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestName + s.Namespace = test.TestNamespace + s.Labels = test.TestKVP + s.Annotations = test.TestKVP + s.StringData = test.TestKVP s.Type = corev1.SecretTypeBasicAuth }), wantErr: false, @@ -72,23 +56,23 @@ func TestRequestSecret(t *testing.T) { name: "request secret, successful mutation", deployReq: SecretRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, - StringData: testKVP, + StringData: test.TestKVP, Mutations: []mutation.MutateFunc{ testMutationFuncSuccessful, }, Client: testClient, }, - desiredSecret: getTestSecret(func(s *corev1.Secret) { - s.Name = testNameMutated - s.Namespace = testNamespace - s.Labels = testKVP - s.Annotations = testKVP - s.StringData = testKVPMutated + desiredSecret: test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestNameMutated + s.Namespace = test.TestNamespace + s.Labels = test.TestKVP + s.Annotations = test.TestKVP + s.StringData = test.TestKVPMutated }), wantErr: false, }, @@ -96,21 +80,21 @@ func TestRequestSecret(t *testing.T) { name: "request secret, failed mutation", deployReq: SecretRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredSecret: getTestSecret(func(s *corev1.Secret) { - s.Name = testName - s.Namespace = testNamespace - s.Labels = testKVP - s.Annotations = testKVP + desiredSecret: test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestName + s.Namespace = test.TestNamespace + s.Labels = test.TestKVP + s.Annotations = test.TestKVP }), wantErr: true, }, @@ -135,24 +119,24 @@ func TestRequestSecret(t *testing.T) { func TestCreateSecret(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredSecret := getTestSecret(func(s *corev1.Secret) { + desiredSecret := test.MakeTestSecret(func(s *corev1.Secret) { s.TypeMeta = metav1.TypeMeta{ Kind: "Secret", APIVersion: "v1", } - s.Name = testName - s.Namespace = testNamespace - s.Labels = testKVP - s.Annotations = testKVP - s.StringData = testKVP + s.Name = test.TestName + s.Namespace = test.TestNamespace + s.Labels = test.TestKVP + s.Annotations = test.TestKVP + s.StringData = test.TestKVP }) err := CreateSecret(desiredSecret, testClient) assert.NoError(t, err) createdSecret := &corev1.Secret{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdSecret) assert.NoError(t, err) @@ -160,36 +144,36 @@ func TestCreateSecret(t *testing.T) { } func TestGetSecret(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestSecret(func(s *corev1.Secret) { - s.Name = testName - s.Namespace = testNamespace - s.StringData = testKVP + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestName + s.Namespace = test.TestNamespace + s.StringData = test.TestKVP })).Build() - _, err := GetSecret(testName, testNamespace, testClient) + _, err := GetSecret(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetSecret(testName, testNamespace, testClient) + _, err = GetSecret(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListSecrets(t *testing.T) { - secret1 := getTestSecret(func(s *corev1.Secret) { + secret1 := test.MakeTestSecret(func(s *corev1.Secret) { s.Name = "secret-1" s.Labels[common.AppK8sKeyComponent] = "new-component-1" - s.Namespace = testNamespace + s.Namespace = test.TestNamespace }) - secret2 := getTestSecret(func(s *corev1.Secret) { + secret2 := test.MakeTestSecret(func(s *corev1.Secret) { s.Name = "secret-2" - s.Namespace = testNamespace + s.Namespace = test.TestNamespace }) - secret3 := getTestSecret(func(s *corev1.Secret) { + secret3 := test.MakeTestSecret(func(s *corev1.Secret) { s.Name = "secret-3" s.Labels[common.AppK8sKeyComponent] = "new-component-2" - s.Namespace = testNamespace + s.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -206,7 +190,7 @@ func TestListSecrets(t *testing.T) { desiredSecrets := []string{"secret-1", "secret-3"} - existingSecretList, err := ListSecrets(testNamespace, testClient, listOpts) + existingSecretList, err := ListSecrets(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingSecrets := []string{} @@ -219,14 +203,14 @@ func TestListSecrets(t *testing.T) { } func TestUpdateSecret(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestSecret(func(s *corev1.Secret) { - s.Name = testName - s.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestName + s.Namespace = test.TestNamespace })).Build() - desiredSecret := getTestSecret(func(s *corev1.Secret) { - s.Name = testName - s.Namespace = testNamespace + desiredSecret := test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestName + s.Namespace = test.TestNamespace s.Data = map[string][]byte{ "admin.password": []byte("testpassword2023"), } @@ -236,36 +220,36 @@ func TestUpdateSecret(t *testing.T) { existingSecret := &corev1.Secret{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingSecret) assert.NoError(t, err) assert.Equal(t, desiredSecret.Data, existingSecret.Data) testClient = fake.NewClientBuilder().Build() - existingSecret = getTestSecret(func(d *corev1.Secret) { - d.Name = testName + existingSecret = test.MakeTestSecret(func(d *corev1.Secret) { + d.Name = test.TestName }) err = UpdateSecret(existingSecret, testClient) assert.Error(t, err) } func TestDeleteSecret(t *testing.T) { - testSecret := getTestSecret(func(s *corev1.Secret) { - s.Name = testName - s.Namespace = testNamespace + testSecret := test.MakeTestSecret(func(s *corev1.Secret) { + s.Name = test.TestName + s.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testSecret).Build() - err := DeleteSecret(testName, testNamespace, testClient) + err := DeleteSecret(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingSecret := &corev1.Secret{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingSecret) assert.Error(t, err) diff --git a/pkg/workloads/statefulset_test.go b/pkg/workloads/statefulset_test.go index fe2f8b74e..574078aa2 100644 --- a/pkg/workloads/statefulset_test.go +++ b/pkg/workloads/statefulset_test.go @@ -17,27 +17,9 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/mutation" + "github.com/argoproj-labs/argocd-operator/tests/test" ) -type statefulSetOpt func(*appsv1.StatefulSet) - -func getTestStatefulSet(opts ...statefulSetOpt) *appsv1.StatefulSet { - desiredStatefulSet := &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: appsv1.StatefulSetSpec{ - Selector: &metav1.LabelSelector{}, - }, - } - - for _, opt := range opts { - opt(desiredStatefulSet) - } - return desiredStatefulSet -} - func TestRequestStatefulSet(t *testing.T) { testClient := fake.NewClientBuilder().Build() @@ -49,26 +31,26 @@ func TestRequestStatefulSet(t *testing.T) { wantErr bool }{ { - name: "request StatefulSet, no mutation, custom name, labels", + name: "request StatefulSet", statefultSetReq: StatefulSetRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: appsv1.StatefulSetSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: testKVP, + MatchLabels: test.TestKVP, }, }, }, - desiredStatefulSet: getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testName - ss.Namespace = testNamespace - ss.Labels = testKVP - ss.Annotations = testKVP - ss.Spec.Selector.MatchLabels = testKVP + desiredStatefulSet: test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestName + ss.Namespace = test.TestNamespace + ss.Labels = test.TestKVP + ss.Annotations = test.TestKVP + ss.Spec.Selector.MatchLabels = test.TestKVP }), wantErr: false, }, @@ -76,14 +58,14 @@ func TestRequestStatefulSet(t *testing.T) { name: "request StatefulSet, successful mutation", statefultSetReq: StatefulSetRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Spec: appsv1.StatefulSetSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: testKVP, + MatchLabels: test.TestKVP, }, }, Mutations: []mutation.MutateFunc{ @@ -91,13 +73,13 @@ func TestRequestStatefulSet(t *testing.T) { }, Client: testClient, }, - desiredStatefulSet: getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testNameMutated - ss.Namespace = testNamespace - ss.Labels = testKVP - ss.Annotations = testKVP + desiredStatefulSet: test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestNameMutated + ss.Namespace = test.TestNamespace + ss.Labels = test.TestKVP + ss.Annotations = test.TestKVP ss.Spec.Replicas = &testReplicasMutated - ss.Spec.Selector.MatchLabels = testKVP + ss.Spec.Selector.MatchLabels = test.TestKVP }), wantErr: false, }, @@ -105,21 +87,21 @@ func TestRequestStatefulSet(t *testing.T) { name: "request StatefulSet, failed mutation", statefultSetReq: StatefulSetRequest{ ObjectMeta: metav1.ObjectMeta{ - Name: testName, - Namespace: testNamespace, - Labels: testKVP, - Annotations: testKVP, + Name: test.TestName, + Namespace: test.TestNamespace, + Labels: test.TestKVP, + Annotations: test.TestKVP, }, Mutations: []mutation.MutateFunc{ - testMutationFuncFailed, + test.TestMutationFuncFailed, }, Client: testClient, }, - desiredStatefulSet: getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testNameMutated - ss.Namespace = testNamespace - ss.Labels = testKVP - ss.Annotations = testKVP + desiredStatefulSet: test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestNameMutated + ss.Namespace = test.TestNamespace + ss.Labels = test.TestKVP + ss.Annotations = test.TestKVP }), wantErr: true, }, @@ -144,23 +126,23 @@ func TestRequestStatefulSet(t *testing.T) { func TestCreateStatefulSet(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredStatefulSet := getTestStatefulSet(func(ss *appsv1.StatefulSet) { + desiredStatefulSet := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { ss.TypeMeta = metav1.TypeMeta{ Kind: "StatefulSet", APIVersion: "apps/v1", } - ss.Name = testName - ss.Namespace = testNamespace - ss.Labels = testKVP - ss.Annotations = testKVP + ss.Name = test.TestName + ss.Namespace = test.TestNamespace + ss.Labels = test.TestKVP + ss.Annotations = test.TestKVP }) err := CreateStatefulSet(desiredStatefulSet, testClient) assert.NoError(t, err) createdStatefulSet := &appsv1.StatefulSet{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, createdStatefulSet) assert.NoError(t, err) @@ -168,36 +150,36 @@ func TestCreateStatefulSet(t *testing.T) { } func TestGetStatefulSet(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testName - ss.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestName + ss.Namespace = test.TestNamespace })).Build() - _, err := GetStatefulSet(testName, testNamespace, testClient) + _, err := GetStatefulSet(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) testClient = fake.NewClientBuilder().Build() - _, err = GetStatefulSet(testName, testNamespace, testClient) + _, err = GetStatefulSet(test.TestName, test.TestNamespace, testClient) assert.Error(t, err) assert.True(t, apierrors.IsNotFound(err)) } func TestListStatefulSets(t *testing.T) { - StatefulSet1 := getTestStatefulSet(func(ss *appsv1.StatefulSet) { + StatefulSet1 := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { ss.Name = "StatefulSet-1" - ss.Namespace = testNamespace + ss.Namespace = test.TestNamespace ss.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - StatefulSet2 := getTestStatefulSet(func(ss *appsv1.StatefulSet) { + StatefulSet2 := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { ss.Name = "StatefulSet-2" - ss.Namespace = testNamespace + ss.Namespace = test.TestNamespace }) - StatefulSet3 := getTestStatefulSet(func(ss *appsv1.StatefulSet) { + StatefulSet3 := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { ss.Name = "StatefulSet-3" ss.Labels[common.AppK8sKeyComponent] = "new-component-2" - ss.Namespace = testNamespace + ss.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects( @@ -214,7 +196,7 @@ func TestListStatefulSets(t *testing.T) { desiredStatefulSets := []string{"StatefulSet-1", "StatefulSet-3"} - existingStatefulSetList, err := ListStatefulSets(testNamespace, testClient, listOpts) + existingStatefulSetList, err := ListStatefulSets(test.TestNamespace, testClient, listOpts) assert.NoError(t, err) existingStatefulSets := []string{} @@ -227,14 +209,14 @@ func TestListStatefulSets(t *testing.T) { } func TestUpdateStatefulSet(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testName - ss.Namespace = testNamespace + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestName + ss.Namespace = test.TestNamespace })).Build() - desiredStatefulSet := getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testName - ss.Namespace = testNamespace + desiredStatefulSet := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestName + ss.Namespace = test.TestNamespace ss.Spec.Template.Spec.NodeSelector = map[string]string{ "kubernetes.io/os": "linux", } @@ -245,36 +227,36 @@ func TestUpdateStatefulSet(t *testing.T) { existingStatefulSet := &appsv1.StatefulSet{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingStatefulSet) assert.NoError(t, err) assert.Equal(t, desiredStatefulSet.Spec, existingStatefulSet.Spec) testClient = fake.NewClientBuilder().Build() - existingStatefulSet = getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testName + existingStatefulSet = test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestName }) err = UpdateStatefulSet(existingStatefulSet, testClient) assert.Error(t, err) } func TestDeleteStatefulSet(t *testing.T) { - testss := getTestStatefulSet(func(ss *appsv1.StatefulSet) { - ss.Name = testName - ss.Namespace = testNamespace + testss := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + ss.Name = test.TestName + ss.Namespace = test.TestNamespace }) testClient := fake.NewClientBuilder().WithObjects(testss).Build() - err := DeleteStatefulSet(testName, testNamespace, testClient) + err := DeleteStatefulSet(test.TestName, test.TestNamespace, testClient) assert.NoError(t, err) existingStatefulSet := &appsv1.StatefulSet{} err = testClient.Get(context.TODO(), types.NamespacedName{ - Namespace: testNamespace, - Name: testName, + Namespace: test.TestNamespace, + Name: test.TestName, }, existingStatefulSet) assert.Error(t, err) diff --git a/pkg/workloads/workloads_test.go b/pkg/workloads/workloads_test.go index ff378ab8b..92512077e 100644 --- a/pkg/workloads/workloads_test.go +++ b/pkg/workloads/workloads_test.go @@ -10,57 +10,38 @@ import ( cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/tests/test" ) // common test variables used across workloads tests var ( - testName = "test-name" - testInstance = "test-instance" - testInstanceNamespace = "test-instance-ns" - testNamespace = "test-ns" - testComponent = "test-component" - testKey = "test-key" - testVal = "test-value" - testValMutated = "test-value-mutated" - - testNameMutated = "mutated-name" testReplicasMutated = int32(4) - testKVP = map[string]string{ - testKey: testVal, - } - testKVPMutated = map[string]string{ - testKey: testValMutated, - } ) -func testMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return errors.New("test-mutation-error") -} - func testMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { switch obj := resource.(type) { case *appsv1.Deployment: - obj.Name = testNameMutated + obj.Name = test.TestNameMutated obj.Spec.Replicas = &testReplicasMutated return nil case *appsv1.StatefulSet: - obj.Name = testNameMutated + obj.Name = test.TestNameMutated obj.Spec.Replicas = &testReplicasMutated return nil case *oappsv1.DeploymentConfig: - obj.Name = testNameMutated + obj.Name = test.TestNameMutated obj.Spec.Replicas = testReplicasMutated return nil case *corev1.Secret: - obj.Name = testNameMutated - obj.StringData = testKVPMutated + obj.Name = test.TestNameMutated + obj.StringData = test.TestKVPMutated return nil case *corev1.ConfigMap: - obj.Name = testNameMutated - obj.Data = testKVPMutated + obj.Name = test.TestNameMutated + obj.Data = test.TestKVPMutated return nil case *autoscaling.HorizontalPodAutoscaler: - obj.Name = testNameMutated + obj.Name = test.TestNameMutated obj.Spec.MaxReplicas = testReplicasMutated return nil } diff --git a/tests/test/testing.go b/tests/test/testing.go new file mode 100644 index 000000000..261b4e5fa --- /dev/null +++ b/tests/test/testing.go @@ -0,0 +1,370 @@ +package test + +import ( + "errors" + + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + TestArgoCDName = "test-argocd" + TestName = "test-name" + TestInstance = "test-instance" + TestInstanceNamespace = "test-instance-ns" + TestNamespace = "test-ns" + TestComponent = "test-component" + TestApplicationName = "test-application-name" + TestKey = "test-key" + TestVal = "test-val" + TestValMutated = "test-val-mutated" + TestNameMutated = "test-name-mutated" +) + +var ( + TestKVP = map[string]string{ + TestKey: TestVal, + } + TestKVPMutated = map[string]string{ + TestKey: TestValMutated, + } +) + +func TestMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { + return errors.New("test-mutation-error") +} + +func TestMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { + return nil +} + +type argoCDOpt func(*argoproj.ArgoCD) + +func MakeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { + a := &argoproj.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestArgoCDName, + Namespace: TestNamespace, + }, + } + for _, o := range opts { + o(a) + } + return a +} + +type namespaceOpt func(*corev1.Namespace) + +func MakeTestNamespace(opts ...namespaceOpt) *corev1.Namespace { + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestNamespace, + Labels: make(map[string]string), + }, + } + for _, o := range opts { + o(ns) + } + return ns +} + +type statefulSetOpt func(*appsv1.StatefulSet) + +func MakeTestStatefulSet(opts ...statefulSetOpt) *appsv1.StatefulSet { + desiredStatefulSet := &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{}, + }, + } + + for _, opt := range opts { + opt(desiredStatefulSet) + } + return desiredStatefulSet +} + +type deploymentOpt func(*appsv1.Deployment) + +func MakeTestDeployment(opts ...deploymentOpt) *appsv1.Deployment { + d := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{}, + }, + } + for _, o := range opts { + o(d) + } + return d +} + +type hpaOpt func(*autoscalingv1.HorizontalPodAutoscaler) + +func MakeTestHPA(opts ...hpaOpt) *autoscalingv1.HorizontalPodAutoscaler { + hpa := &autoscalingv1.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: autoscalingv1.HorizontalPodAutoscalerSpec{}, + } + for _, o := range opts { + o(hpa) + } + return hpa +} + +type podOpt func(*corev1.Pod) + +func MakeTestPod(opts ...podOpt) *corev1.Pod { + p := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + }, + } + for _, o := range opts { + o(p) + } + return p +} + +type serviceOpt func(*corev1.Service) + +func MakeTestService(opts ...serviceOpt) *corev1.Service { + s := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(s) + } + return s +} + +type configMapOpt func(*corev1.ConfigMap) + +func MakeTestConfigMap(opts ...configMapOpt) *corev1.ConfigMap { + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Data: make(map[string]string), + } + for _, o := range opts { + o(cm) + } + return cm +} + +type secretOpt func(*corev1.Secret) + +func MakeTestSecret(opts ...secretOpt) *corev1.Secret { + s := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + StringData: map[string]string{}, + } + for _, o := range opts { + o(s) + } + return s +} + +type roleOpt func(*rbacv1.Role) + +func MakeTestRole(opts ...roleOpt) *rbacv1.Role { + r := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Rules: TestRules, + } + for _, o := range opts { + o(r) + } + return r +} + +func MakeTestRoleRef(name string) rbacv1.RoleRef { + return rbacv1.RoleRef{ + Kind: "Role", + Name: name, + APIGroup: "rbac.authorization.k8s.io", + } +} + +func MakeTestSubjects(subs ...types.NamespacedName) []rbacv1.Subject { + subjects := []rbacv1.Subject{} + + for _, subj := range subs { + subjects = append(subjects, rbacv1.Subject{ + Kind: rbacv1.ServiceAccountKind, + Name: subj.Name, + Namespace: subj.Namespace, + }) + } + return subjects +} + +var ( + TestRules = []rbacv1.PolicyRule{ + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "pods", + }, + Verbs: []string{ + "create", + }, + }, + } +) + +type roleBindingOpt func(*rbacv1.RoleBinding) + +func MakeTestRoleBinding(opts ...roleBindingOpt) *rbacv1.RoleBinding { + rb := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(rb) + } + return rb +} + +type clusterRoleOpt func(*rbacv1.ClusterRole) + +func MakeTestClusterRole(opts ...clusterRoleOpt) *rbacv1.ClusterRole { + cr := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Rules: TestRules, + } + for _, o := range opts { + o(cr) + } + return cr +} + +type clusterRoleBindingOpt func(*rbacv1.ClusterRoleBinding) + +func MakeTestClusterRoleBinding(opts ...clusterRoleBindingOpt) *rbacv1.ClusterRoleBinding { + crb := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: TestName, + APIGroup: "rbac.authorization.k8s.io", + }, + } + for _, o := range opts { + o(crb) + } + return crb +} + +type serviceAccountOpt func(*corev1.ServiceAccount) + +func MakeTestServiceAccount(opts ...serviceAccountOpt) *corev1.ServiceAccount { + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(sa) + } + return sa +} + +type serviceMonitorOpt func(*monitoringv1.ServiceMonitor) + +func MakeTestServiceMonitor(opts ...serviceMonitorOpt) *monitoringv1.ServiceMonitor { + sm := &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: TestKVP, + }, + }, + } + for _, o := range opts { + o(sm) + } + return sm +} + +type prometheusRuleOpt func(*monitoringv1.PrometheusRule) + +func MakeTestPrometheusRule(opts ...prometheusRuleOpt) *monitoringv1.PrometheusRule { + pr := &monitoringv1.PrometheusRule{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(pr) + } + return pr +} From 0f2da83516725d03ade941af8091b91cfc153666 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 13:56:33 -0500 Subject: [PATCH 70/94] split argocd tbr file Signed-off-by: Jaideep Rao --- controllers/argocd/TOBEREMOVED.go | 1777 ++--------------- .../argocd/appcontroller_TOBEREMOVED.go | 1 + controllers/argocd/appset_TOBEREMOVED.go | 577 ++++++ controllers/argocd/argocd_controller.go | 134 -- controllers/argocd/cm_TOBEREMOVED.go | 1 + controllers/argocd/dex_TOBEREMOVED.go | 1 + controllers/argocd/keycloak_TOBEREMOVED.go | 1 + .../argocd/notifications_TOBEREMOVED.go | 1098 ++++++++++ controllers/argocd/redis_TOBEREMOVED.go | 1 + controllers/argocd/reposerver_TOBEREMOVED.go | 1 + controllers/argocd/secret_TOBEREMOVED.go | 1 + controllers/argocd/server_TOBEREMOVED.go | 1 + 12 files changed, 1818 insertions(+), 1776 deletions(-) create mode 100644 controllers/argocd/appcontroller_TOBEREMOVED.go create mode 100644 controllers/argocd/appset_TOBEREMOVED.go create mode 100644 controllers/argocd/cm_TOBEREMOVED.go create mode 100644 controllers/argocd/dex_TOBEREMOVED.go create mode 100644 controllers/argocd/keycloak_TOBEREMOVED.go create mode 100644 controllers/argocd/notifications_TOBEREMOVED.go create mode 100644 controllers/argocd/redis_TOBEREMOVED.go create mode 100644 controllers/argocd/reposerver_TOBEREMOVED.go create mode 100644 controllers/argocd/secret_TOBEREMOVED.go create mode 100644 controllers/argocd/server_TOBEREMOVED.go diff --git a/controllers/argocd/TOBEREMOVED.go b/controllers/argocd/TOBEREMOVED.go index d789f2337..2b070888d 100644 --- a/controllers/argocd/TOBEREMOVED.go +++ b/controllers/argocd/TOBEREMOVED.go @@ -8,12 +8,12 @@ import ( "errors" "fmt" "os" - "reflect" "strings" "text/template" "time" argopass "github.com/argoproj/argo-cd/v2/util/password" + "github.com/prometheus/client_golang/prometheus" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -29,19 +29,18 @@ import ( "github.com/sethvargo/go-password/password" "golang.org/x/mod/semver" "gopkg.in/yaml.v2" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" + ctrlLog "sigs.k8s.io/controller-runtime/pkg/log" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/config" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/reconcile" ) // DeprecationEventEmissionStatus is meant to track which deprecation events have been emitted already. This is temporary and can be removed in v0.0.6 once we have provided enough @@ -458,1643 +457,6 @@ func getArgoContainerImage(cr *argoproj.ArgoCD) string { return argoutil.CombineImageTag(img, tag) } -// getNotificationsResources will return the ResourceRequirements for the Notifications container. -func getNotificationsResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { - resources := corev1.ResourceRequirements{} - - // Allow override of resource requirements from CR - if cr.Spec.Notifications.Resources != nil { - resources = *cr.Spec.Notifications.Resources - } - - return resources -} - -func getNotificationsCommand(cr *argoproj.ArgoCD) []string { - - cmd := make([]string, 0) - cmd = append(cmd, "argocd-notifications") - - cmd = append(cmd, "--loglevel") - cmd = append(cmd, getLogLevel(cr.Spec.Notifications.LogLevel)) - - return cmd -} - -// reconcileNotificationsConfigMap only creates/deletes the argocd-notifications-cm based on whether notifications is enabled/disabled in the CR -// It does not reconcile/overwrite any fields or information in the configmap itself -func (r *ReconcileArgoCD) reconcileNotificationsConfigMap(cr *argoproj.ArgoCD) error { - - desiredConfigMap := newConfigMapWithName("argocd-notifications-cm", cr) - desiredConfigMap.Data = getDefaultNotificationsConfig() - - cmExists := true - existingConfigMap := &corev1.ConfigMap{} - if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredConfigMap.Name, existingConfigMap); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to get the configmap associated with %s : %s", desiredConfigMap.Name, err) - } - cmExists = false - } - - if cmExists { - // CM exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting configmap %s as notifications is disabled", existingConfigMap.Name)) - return r.Client.Delete(context.TODO(), existingConfigMap) - } - - // CM exists and should, nothing to do here - return nil - } - - // CM doesn't exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // CM doesn't exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredConfigMap, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating configmap %s", desiredConfigMap.Name)) - err := r.Client.Create(context.TODO(), desiredConfigMap) - if err != nil { - return err - } - - return nil -} - -// reconcileNotificationsSecret only creates/deletes the argocd-notifications-secret based on whether notifications is enabled/disabled in the CR -// It does not reconcile/overwrite any fields or information in the secret itself -func (r *ReconcileArgoCD) reconcileNotificationsSecret(cr *argoproj.ArgoCD) error { - - desiredSecret := argoutil.NewSecretWithName(cr, "argocd-notifications-secret") - - secretExists := true - existingSecret := &corev1.Secret{} - if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredSecret.Name, existingSecret); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to get the secret associated with %s : %s", desiredSecret.Name, err) - } - secretExists = false - } - - if secretExists { - // secret exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting secret %s as notifications is disabled", existingSecret.Name)) - return r.Client.Delete(context.TODO(), existingSecret) - } - - // secret exists and should, nothing to do here - return nil - } - - // secret doesn't exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // secret doesn't exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredSecret, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating secret %s", desiredSecret.Name)) - err := r.Client.Create(context.TODO(), desiredSecret) - if err != nil { - return err - } - - return nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsController(cr *argoproj.ArgoCD) error { - - log.Info("reconciling notifications serviceaccount") - sa, err := r.reconcileNotificationsServiceAccount(cr) - if err != nil { - return err - } - - log.Info("reconciling notifications role") - role, err := r.reconcileNotificationsRole(cr) - if err != nil { - return err - } - - log.Info("reconciling notifications role binding") - if err := r.reconcileNotificationsRoleBinding(cr, role, sa); err != nil { - return err - } - - log.Info("reconciling notifications configmap") - if err := r.reconcileNotificationsConfigMap(cr); err != nil { - return err - } - - log.Info("reconciling notifications secret") - if err := r.reconcileNotificationsSecret(cr); err != nil { - return err - } - - log.Info("reconciling notifications deployment") - if err := r.reconcileNotificationsDeployment(cr, sa); err != nil { - return err - } - - return nil -} - -// The code to create/delete notifications resources is written within the reconciliation logic itself. However, these functions must be called -// in the right order depending on whether resources are getting created or deleted. During creation we must create the role and sa first. -// RoleBinding and deployment are dependent on these resouces. During deletion the order is reversed. -// Deployment and RoleBinding must be deleted before the role and sa. deleteNotificationsResources will only be called during -// delete events, so we don't need to worry about duplicate, recurring reconciliation calls -func (r *ReconcileArgoCD) deleteNotificationsResources(cr *argoproj.ArgoCD) error { - - sa := &corev1.ServiceAccount{} - role := &rbacv1.Role{} - - if err := argoutil.FetchObject(r.Client, cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDNotificationsControllerComponent), sa); err != nil { - if !apierrors.IsNotFound(err) { - return err - } - } - if err := argoutil.FetchObject(r.Client, cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDNotificationsControllerComponent), role); err != nil { - if !apierrors.IsNotFound(err) { - return err - } - } - - log.Info("reconciling notifications deployment") - if err := r.reconcileNotificationsDeployment(cr, sa); err != nil { - return err - } - - log.Info("reconciling notifications secret") - if err := r.reconcileNotificationsSecret(cr); err != nil { - return err - } - - log.Info("reconciling notifications configmap") - if err := r.reconcileNotificationsConfigMap(cr); err != nil { - return err - } - - log.Info("reconciling notifications role binding") - if err := r.reconcileNotificationsRoleBinding(cr, role, sa); err != nil { - return err - } - - log.Info("reconciling notifications role") - _, err := r.reconcileNotificationsRole(cr) - if err != nil { - return err - } - - log.Info("reconciling notifications serviceaccount") - _, err = r.reconcileNotificationsServiceAccount(cr) - if err != nil { - return err - } - - return nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { - - sa := newServiceAccountWithName(common.ArgoCDNotificationsControllerComponent, cr) - - if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { - if !apierrors.IsNotFound(err) { - return nil, fmt.Errorf("failed to get the serviceAccount associated with %s : %s", sa.Name, err) - } - - // SA doesn't exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil, nil - } - - // SA doesn't exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, sa, r.Scheme); err != nil { - return nil, err - } - - log.Info(fmt.Sprintf("Creating serviceaccount %s", sa.Name)) - err := r.Client.Create(context.TODO(), sa) - if err != nil { - return nil, err - } - } - - // SA exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting serviceaccount %s as notifications is disabled", sa.Name)) - return nil, r.Client.Delete(context.TODO(), sa) - } - - return sa, nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsRole(cr *argoproj.ArgoCD) (*rbacv1.Role, error) { - - policyRules := policyRuleForNotificationsController() - desiredRole := newRole(common.ArgoCDNotificationsControllerComponent, policyRules, cr) - - existingRole := &rbacv1.Role{} - if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredRole.Name, existingRole); err != nil { - if !apierrors.IsNotFound(err) { - return nil, fmt.Errorf("failed to get the role associated with %s : %s", desiredRole.Name, err) - } - - // role does not exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil, nil - } - - // role does not exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredRole, r.Scheme); err != nil { - return nil, err - } - - log.Info(fmt.Sprintf("Creating role %s", desiredRole.Name)) - err := r.Client.Create(context.TODO(), desiredRole) - if err != nil { - return nil, err - } - return desiredRole, nil - } - - // role exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting role %s as notifications is disabled", existingRole.Name)) - return nil, r.Client.Delete(context.TODO(), existingRole) - } - - // role exists and should. Reconcile role if changed - if !reflect.DeepEqual(existingRole.Rules, desiredRole.Rules) { - existingRole.Rules = desiredRole.Rules - if err := controllerutil.SetControllerReference(cr, existingRole, r.Scheme); err != nil { - return nil, err - } - return existingRole, r.Client.Update(context.TODO(), existingRole) - } - - return desiredRole, nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoproj.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { - - desiredRoleBinding := newRoleBindingWithname(common.ArgoCDNotificationsControllerComponent, cr) - desiredRoleBinding.RoleRef = rbacv1.RoleRef{ - APIGroup: rbacv1.GroupName, - Kind: "Role", - Name: role.Name, - } - - desiredRoleBinding.Subjects = []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: sa.Name, - Namespace: sa.Namespace, - }, - } - - // fetch existing rolebinding by name - existingRoleBinding := &rbacv1.RoleBinding{} - if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: desiredRoleBinding.Name, Namespace: cr.Namespace}, existingRoleBinding); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to get the rolebinding associated with %s : %s", desiredRoleBinding.Name, err) - } - - // roleBinding does not exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // roleBinding does not exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredRoleBinding, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating roleBinding %s", desiredRoleBinding.Name)) - return r.Client.Create(context.TODO(), desiredRoleBinding) - } - - // roleBinding exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting roleBinding %s as notifications is disabled", existingRoleBinding.Name)) - return r.Client.Delete(context.TODO(), existingRoleBinding) - } - - // roleBinding exists and should. Reconcile roleBinding if changed - if !reflect.DeepEqual(existingRoleBinding.RoleRef, desiredRoleBinding.RoleRef) { - // if the RoleRef changes, delete the existing role binding and create a new one - if err := r.Client.Delete(context.TODO(), existingRoleBinding); err != nil { - return err - } - } else if !reflect.DeepEqual(existingRoleBinding.Subjects, desiredRoleBinding.Subjects) { - existingRoleBinding.Subjects = desiredRoleBinding.Subjects - if err := controllerutil.SetControllerReference(cr, existingRoleBinding, r.Scheme); err != nil { - return err - } - return r.Client.Update(context.TODO(), existingRoleBinding) - } - - return nil -} - -func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { - - desiredDeployment := newDeploymentWithSuffix("notifications-controller", "controller", cr) - - desiredDeployment.Spec.Strategy = appsv1.DeploymentStrategy{ - Type: appsv1.RecreateDeploymentStrategyType, - } - - if replicas := getArgoCDNotificationsControllerReplicas(cr); replicas != nil { - desiredDeployment.Spec.Replicas = replicas - } - - notificationEnv := cr.Spec.Notifications.Env - // Let user specify their own environment first - notificationEnv = argoutil.EnvMerge(notificationEnv, proxyEnvVars(), false) - - podSpec := &desiredDeployment.Spec.Template.Spec - podSpec.SecurityContext = &corev1.PodSecurityContext{ - RunAsNonRoot: boolPtr(true), - } - AddSeccompProfileForOpenShift(r.Client, podSpec) - podSpec.ServiceAccountName = sa.ObjectMeta.Name - podSpec.Volumes = []corev1.Volume{ - { - Name: "tls-certs", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDTLSCertsConfigMapName, - }, - }, - }, - }, - { - Name: "argocd-repo-server-tls", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: common.ArgoCDRepoServerTLSSecretName, - Optional: boolPtr(true), - }, - }, - }, - } - - podSpec.Containers = []corev1.Container{{ - Command: getNotificationsCommand(cr), - Image: getArgoContainerImage(cr), - ImagePullPolicy: corev1.PullAlways, - Name: common.ArgoCDNotificationsControllerComponent, - Env: notificationEnv, - Resources: getNotificationsResources(cr), - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.IntOrString{ - IntVal: int32(9001), - }, - }, - }, - }, - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "tls-certs", - MountPath: "/app/config/tls", - }, - { - Name: "argocd-repo-server-tls", - MountPath: "/app/config/reposerver/tls", - }, - }, - WorkingDir: "/app", - }} - - // fetch existing deployment by name - deploymentChanged := false - existingDeployment := &appsv1.Deployment{} - if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: desiredDeployment.Name, Namespace: cr.Namespace}, existingDeployment); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to get the deployment associated with %s : %s", existingDeployment.Name, err) - } - - // deployment does not exist and shouldn't, nothing to do here - if !cr.Spec.Notifications.Enabled { - return nil - } - - // deployment does not exist but should, so it should be created - if err := controllerutil.SetControllerReference(cr, desiredDeployment, r.Scheme); err != nil { - return err - } - - log.Info(fmt.Sprintf("Creating deployment %s", desiredDeployment.Name)) - return r.Client.Create(context.TODO(), desiredDeployment) - } - - // deployment exists but shouldn't, so it should be deleted - if !cr.Spec.Notifications.Enabled { - log.Info(fmt.Sprintf("Deleting deployment %s as notifications is disabled", existingDeployment.Name)) - return r.Client.Delete(context.TODO(), existingDeployment) - } - - // deployment exists and should. Reconcile deployment if changed - updateNodePlacement(existingDeployment, desiredDeployment, &deploymentChanged) - - if existingDeployment.Spec.Template.Spec.Containers[0].Image != desiredDeployment.Spec.Template.Spec.Containers[0].Image { - existingDeployment.Spec.Template.Spec.Containers[0].Image = desiredDeployment.Spec.Template.Spec.Containers[0].Image - existingDeployment.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Command, desiredDeployment.Spec.Template.Spec.Containers[0].Command) { - existingDeployment.Spec.Template.Spec.Containers[0].Command = desiredDeployment.Spec.Template.Spec.Containers[0].Command - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Env, - desiredDeployment.Spec.Template.Spec.Containers[0].Env) { - existingDeployment.Spec.Template.Spec.Containers[0].Env = desiredDeployment.Spec.Template.Spec.Containers[0].Env - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Volumes, desiredDeployment.Spec.Template.Spec.Volumes) { - existingDeployment.Spec.Template.Spec.Volumes = desiredDeployment.Spec.Template.Spec.Volumes - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Replicas, desiredDeployment.Spec.Replicas) { - existingDeployment.Spec.Replicas = desiredDeployment.Spec.Replicas - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts) { - existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts = desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Resources, desiredDeployment.Spec.Template.Spec.Containers[0].Resources) { - existingDeployment.Spec.Template.Spec.Containers[0].Resources = desiredDeployment.Spec.Template.Spec.Containers[0].Resources - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.ServiceAccountName, desiredDeployment.Spec.Template.Spec.ServiceAccountName) { - existingDeployment.Spec.Template.Spec.ServiceAccountName = desiredDeployment.Spec.Template.Spec.ServiceAccountName - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Labels, desiredDeployment.Labels) { - existingDeployment.Labels = desiredDeployment.Labels - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Template.Labels, desiredDeployment.Spec.Template.Labels) { - existingDeployment.Spec.Template.Labels = desiredDeployment.Spec.Template.Labels - deploymentChanged = true - } - - if !reflect.DeepEqual(existingDeployment.Spec.Selector, desiredDeployment.Spec.Selector) { - existingDeployment.Spec.Selector = desiredDeployment.Spec.Selector - deploymentChanged = true - } - - if deploymentChanged { - return r.Client.Update(context.TODO(), existingDeployment) - } - - return nil - -} - -// getDefaultNotificationsConfig returns a map that contains default triggers and template configurations for argocd-notifications-cm -func getDefaultNotificationsConfig() map[string]string { - - notificationsConfig := make(map[string]string) - - // configure default notifications templates - - notificationsConfig["template.app-created"] = `email: - subject: Application {{.app.metadata.name}} has been created. -message: Application {{.app.metadata.name}} has been created. -teams: - title: Application {{.app.metadata.name}} has been created.` - - notificationsConfig["template.app-deleted"] = `email: - subject: Application {{.app.metadata.name}} has been deleted. -message: Application {{.app.metadata.name}} has been deleted. -teams: - title: Application {{.app.metadata.name}} has been deleted.` - - notificationsConfig["template.app-deployed"] = `email: - subject: New version of an application {{.app.metadata.name}} is up and running. -message: | - {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} is now running new version of deployments manifests. -slack: - attachments: | - [{ - "title": "{{ .app.metadata.name}}", - "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", - "color": "#18be52", - "fields": [ - { - "title": "Sync Status", - "value": "{{.app.status.sync.status}}", - "short": true - }, - { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", - "short": true - }, - { - "title": "Revision", - "value": "{{.app.status.sync.revision}}", - "short": true - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "title": "{{$c.type}}", - "value": "{{$c.message}}", - "short": true - } - {{end}} - ] - }] - deliveryPolicy: Post - groupingKey: "" - notifyBroadcast: false -teams: - facts: | - [{ - "name": "Sync Status", - "value": "{{.app.status.sync.status}}" - }, - { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" - }, - { - "name": "Revision", - "value": "{{.app.status.sync.revision}}" - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "name": "{{$c.type}}", - "value": "{{$c.message}}" - } - {{end}} - ] - potentialAction: |- - [{ - "@type":"OpenUri", - "name":"Operation Application", - "targets":[{ - "os":"default", - "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}" - }] - }, - { - "@type":"OpenUri", - "name":"Open Repository", - "targets":[{ - "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" - }] - }] - themeColor: '#000080' - title: New version of an application {{.app.metadata.name}} is up and running.` - - notificationsConfig["template.app-health-degraded"] = `email: - subject: Application {{.app.metadata.name}} has degraded. -message: | - {{if eq .serviceType "slack"}}:exclamation:{{end}} Application {{.app.metadata.name}} has degraded. - Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. -slack: - attachments: | - [{ - "title": "{{ .app.metadata.name}}", - "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", - "color": "#f4c030", - "fields": [ - { - "title": "Health Status", - "value": "{{.app.status.health.status}}", - "short": true - }, - { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", - "short": true - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "title": "{{$c.type}}", - "value": "{{$c.message}}", - "short": true - } - {{end}} - ] - }] - deliveryPolicy: Post - groupingKey: "" - notifyBroadcast: false -teams: - facts: | - [{ - "name": "Health Status", - "value": "{{.app.status.health.status}}" - }, - { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "name": "{{$c.type}}", - "value": "{{$c.message}}" - } - {{end}} - ] - potentialAction: | - [{ - "@type":"OpenUri", - "name":"Open Application", - "targets":[{ - "os":"default", - "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}" - }] - }, - { - "@type":"OpenUri", - "name":"Open Repository", - "targets":[{ - "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" - }] - }] - themeColor: '#FF0000' - title: Application {{.app.metadata.name}} has degraded.` - - notificationsConfig["template.app-sync-failed"] = `email: - subject: Failed to sync application {{.app.metadata.name}}. -message: | - {{if eq .serviceType "slack"}}:exclamation:{{end}} The sync operation of application {{.app.metadata.name}} has failed at {{.app.status.operationState.finishedAt}} with the following error: {{.app.status.operationState.message}} - Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . -slack: - attachments: | - [{ - "title": "{{ .app.metadata.name}}", - "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", - "color": "#E96D76", - "fields": [ - { - "title": "Sync Status", - "value": "{{.app.status.sync.status}}", - "short": true - }, - { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", - "short": true - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "title": "{{$c.type}}", - "value": "{{$c.message}}", - "short": true - } - {{end}} - ] - }] - deliveryPolicy: Post - groupingKey: "" - notifyBroadcast: false -teams: - facts: | - [{ - "name": "Sync Status", - "value": "{{.app.status.sync.status}}" - }, - { - "name": "Failed at", - "value": "{{.app.status.operationState.finishedAt}}" - }, - { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "name": "{{$c.type}}", - "value": "{{$c.message}}" - } - {{end}} - ] - potentialAction: |- - [{ - "@type":"OpenUri", - "name":"Open Operation", - "targets":[{ - "os":"default", - "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" - }] - }, - { - "@type":"OpenUri", - "name":"Open Repository", - "targets":[{ - "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" - }] - }] - themeColor: '#FF0000' - title: Failed to sync application {{.app.metadata.name}}.` - - notificationsConfig["template.app-sync-running"] = `email: - subject: Start syncing application {{.app.metadata.name}}. -message: | - The sync operation of application {{.app.metadata.name}} has started at {{.app.status.operationState.startedAt}}. - Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . -slack: - attachments: | - [{ - "title": "{{ .app.metadata.name}}", - "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", - "color": "#0DADEA", - "fields": [ - { - "title": "Sync Status", - "value": "{{.app.status.sync.status}}", - "short": true - }, - { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", - "short": true - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "title": "{{$c.type}}", - "value": "{{$c.message}}", - "short": true - } - {{end}} - ] - }] - deliveryPolicy: Post - groupingKey: "" - notifyBroadcast: false -teams: - facts: | - [{ - "name": "Sync Status", - "value": "{{.app.status.sync.status}}" - }, - { - "name": "Started at", - "value": "{{.app.status.operationState.startedAt}}" - }, - { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "name": "{{$c.type}}", - "value": "{{$c.message}}" - } - {{end}} - ] - potentialAction: |- - [{ - "@type":"OpenUri", - "name":"Open Operation", - "targets":[{ - "os":"default", - "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" - }] - }, - { - "@type":"OpenUri", - "name":"Open Repository", - "targets":[{ - "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" - }] - }] - title: Start syncing application {{.app.metadata.name}}.` - - notificationsConfig["template.app-sync-status-unknown"] = `email: - subject: Application {{.app.metadata.name}} sync status is 'Unknown' -message: | - {{if eq .serviceType "slack"}}:exclamation:{{end}} Application {{.app.metadata.name}} sync is 'Unknown'. - Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. - {{if ne .serviceType "slack"}} - {{range $c := .app.status.conditions}} - * {{$c.message}} - {{end}} - {{end}} -slack: - attachments: | - [{ - "title": "{{ .app.metadata.name}}", - "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", - "color": "#E96D76", - "fields": [ - { - "title": "Sync Status", - "value": "{{.app.status.sync.status}}", - "short": true - }, - { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", - "short": true - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "title": "{{$c.type}}", - "value": "{{$c.message}}", - "short": true - } - {{end}} - ] - }] - deliveryPolicy: Post - groupingKey: "" - notifyBroadcast: false -teams: - facts: | - [{ - "name": "Sync Status", - "value": "{{.app.status.sync.status}}" - }, - { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "name": "{{$c.type}}", - "value": "{{$c.message}}" - } - {{end}} - ] - potentialAction: |- - [{ - "@type":"OpenUri", - "name":"Open Application", - "targets":[{ - "os":"default", - "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}" - }] - }, - { - "@type":"OpenUri", - "name":"Open Repository", - "targets":[{ - "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" - }] - }] - title: Application {{.app.metadata.name}} sync status is 'Unknown'` - - notificationsConfig["template.app-sync-succeeded"] = `email: - subject: Application {{.app.metadata.name}} has been successfully synced. -message: | - {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} has been successfully synced at {{.app.status.operationState.finishedAt}}. - Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . -slack: - attachments: | - [{ - "title": "{{ .app.metadata.name}}", - "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", - "color": "#18be52", - "fields": [ - { - "title": "Sync Status", - "value": "{{.app.status.sync.status}}", - "short": true - }, - { - "title": "Repository", - "value": "{{.app.spec.source.repoURL}}", - "short": true - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "title": "{{$c.type}}", - "value": "{{$c.message}}", - "short": true - } - {{end}} - ] - }] - deliveryPolicy: Post - groupingKey: "" - notifyBroadcast: false -teams: - facts: | - [{ - "name": "Sync Status", - "value": "{{.app.status.sync.status}}" - }, - { - "name": "Synced at", - "value": "{{.app.status.operationState.finishedAt}}" - }, - { - "name": "Repository", - "value": "{{.app.spec.source.repoURL}}" - } - {{range $index, $c := .app.status.conditions}} - {{if not $index}},{{end}} - {{if $index}},{{end}} - { - "name": "{{$c.type}}", - "value": "{{$c.message}}" - } - {{end}} - ] - potentialAction: |- - [{ - "@type":"OpenUri", - "name":"Operation Details", - "targets":[{ - "os":"default", - "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" - }] - }, - { - "@type":"OpenUri", - "name":"Open Repository", - "targets":[{ - "os":"default", - "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" - }] - }] - themeColor: '#000080' - title: Application {{.app.metadata.name}} has been successfully synced` - - // configure default notifications triggers - - notificationsConfig["trigger.on-created"] = `- description: Application is created. - oncePer: app.metadata.name - send: - - app-created - when: "true"` - - notificationsConfig["trigger.on-deleted"] = `- description: Application is deleted. - oncePer: app.metadata.name - send: - - app-deleted - when: app.metadata.deletionTimestamp != nil` - - notificationsConfig["trigger.on-deployed"] = `- description: Application is synced and healthy. Triggered once per commit. - oncePer: app.status.operationState.syncResult.revision - send: - - app-deployed - when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status - == 'Healthy'` - - notificationsConfig["trigger.on-health-degraded"] = `- description: Application has degraded - send: - - app-health-degraded - when: app.status.health.status == 'Degraded'` - - notificationsConfig["trigger.on-sync-failed"] = `- description: Application syncing has failed - send: - - app-sync-failed - when: app.status.operationState.phase in ['Error', 'Failed']` - - notificationsConfig["trigger.on-sync-running"] = `- description: Application is being synced - send: - - app-sync-running - when: app.status.operationState.phase in ['Running']` - - notificationsConfig["trigger.on-sync-status-unknown"] = `- description: Application status is 'Unknown' - send: - - app-sync-status-unknown - when: app.status.sync.status == 'Unknown'` - - notificationsConfig["trigger.on-sync-succeeded"] = `- description: Application syncing has succeeded - send: - - app-sync-succeeded - when: app.status.operationState.phase in ['Succeeded']` - - return notificationsConfig -} - -// getArgoCDNotificationsControllerReplicas will return the size value for the argocd-notifications-controller replica count if it -// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or -// replicas value is < 0. -func getArgoCDNotificationsControllerReplicas(cr *argoproj.ArgoCD) *int32 { - if cr.Spec.Notifications.Replicas != nil && *cr.Spec.Notifications.Replicas >= 0 { - return cr.Spec.Notifications.Replicas - } - - return nil -} - -const ( - ApplicationSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" -) - -// getArgoApplicationSetCommand will return the command for the ArgoCD ApplicationSet component. -func getArgoApplicationSetCommand(cr *argoproj.ArgoCD) []string { - cmd := make([]string, 0) - - cmd = append(cmd, "entrypoint.sh") - cmd = append(cmd, "argocd-applicationset-controller") - - if cr.Spec.Repo.IsEnabled() { - cmd = append(cmd, "--argocd-repo-server", getRepoServerAddress(cr)) - } else { - log.Info("Repo Server is disabled. This would affect the functioning of ApplicationSet Controller.") - } - - cmd = append(cmd, "--loglevel") - cmd = append(cmd, getLogLevel(cr.Spec.ApplicationSet.LogLevel)) - - if cr.Spec.ApplicationSet.SCMRootCAConfigMap != "" { - cmd = append(cmd, "--scm-root-ca-path") - cmd = append(cmd, ApplicationSetGitlabSCMTlsCertPath) - } - - // ApplicationSet command arguments provided by the user - extraArgs := cr.Spec.ApplicationSet.ExtraCommandArgs - err := isMergable(extraArgs, cmd) - if err != nil { - return cmd - } - - cmd = append(cmd, extraArgs...) - - return cmd -} - -func (r *ReconcileArgoCD) reconcileApplicationSetController(cr *argoproj.ArgoCD) error { - - log.Info("reconciling applicationset serviceaccounts") - sa, err := r.reconcileApplicationSetServiceAccount(cr) - if err != nil { - return err - } - - log.Info("reconciling applicationset roles") - role, err := r.reconcileApplicationSetRole(cr) - if err != nil { - return err - } - - log.Info("reconciling applicationset role bindings") - if err := r.reconcileApplicationSetRoleBinding(cr, role, sa); err != nil { - return err - } - - log.Info("reconciling applicationset deployments") - if err := r.reconcileApplicationSetDeployment(cr, sa); err != nil { - return err - } - - log.Info("reconciling applicationset service") - if err := r.reconcileApplicationSetService(cr); err != nil { - return err - } - - return nil -} - -// reconcileApplicationControllerDeployment will ensure the Deployment resource is present for the ArgoCD Application Controller component. -func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { - deploy := newDeploymentWithSuffix("applicationset-controller", "controller", cr) - - setAppSetLabels(&deploy.ObjectMeta) - - podSpec := &deploy.Spec.Template.Spec - - // sa would be nil when spec.applicationset.enabled = false - if sa != nil { - podSpec.ServiceAccountName = sa.ObjectMeta.Name - } - podSpec.Volumes = []corev1.Volume{ - { - Name: "ssh-known-hosts", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDKnownHostsConfigMapName, - }, - }, - }, - }, - { - Name: "tls-certs", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDTLSCertsConfigMapName, - }, - }, - }, - }, - { - Name: "gpg-keys", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDGPGKeysConfigMapName, - }, - }, - }, - }, - { - Name: "gpg-keyring", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "tmp", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - } - addSCMGitlabVolumeMount := false - if scmRootCAConfigMapName := getSCMRootCAConfigMapName(cr); scmRootCAConfigMapName != "" { - cm := newConfigMapWithName(scmRootCAConfigMapName, cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, cr.Spec.ApplicationSet.SCMRootCAConfigMap, cm) { - addSCMGitlabVolumeMount = true - podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{ - Name: "appset-gitlab-scm-tls-cert", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, - }, - }, - }, - }) - } - } - - podSpec.Containers = []corev1.Container{ - applicationSetContainer(cr, addSCMGitlabVolumeMount), - } - AddSeccompProfileForOpenShift(r.Client, podSpec) - - if existing := newDeploymentWithSuffix("applicationset-controller", "controller", cr); argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { - - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - err := r.Client.Delete(context.TODO(), existing) - return err - } - - existingSpec := existing.Spec.Template.Spec - - deploymentsDifferent := !reflect.DeepEqual(existingSpec.Containers[0], podSpec.Containers) || - !reflect.DeepEqual(existingSpec.Volumes, podSpec.Volumes) || - existingSpec.ServiceAccountName != podSpec.ServiceAccountName || - !reflect.DeepEqual(existing.Labels, deploy.Labels) || - !reflect.DeepEqual(existing.Spec.Template.Labels, deploy.Spec.Template.Labels) || - !reflect.DeepEqual(existing.Spec.Selector, deploy.Spec.Selector) || - !reflect.DeepEqual(existing.Spec.Template.Spec.NodeSelector, deploy.Spec.Template.Spec.NodeSelector) || - !reflect.DeepEqual(existing.Spec.Template.Spec.Tolerations, deploy.Spec.Template.Spec.Tolerations) - - // If the Deployment already exists, make sure the values we care about are up-to-date - if deploymentsDifferent { - existing.Spec.Template.Spec.Containers = podSpec.Containers - existing.Spec.Template.Spec.Volumes = podSpec.Volumes - existing.Spec.Template.Spec.ServiceAccountName = podSpec.ServiceAccountName - existing.Labels = deploy.Labels - existing.Spec.Template.Labels = deploy.Spec.Template.Labels - existing.Spec.Selector = deploy.Spec.Selector - existing.Spec.Template.Spec.NodeSelector = deploy.Spec.Template.Spec.NodeSelector - existing.Spec.Template.Spec.Tolerations = deploy.Spec.Template.Spec.Tolerations - return r.Client.Update(context.TODO(), existing) - } - return nil // Deployment found with nothing to do, move along... - } - - if !cr.Spec.ApplicationSet.IsEnabled() { - return nil - } - - if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), deploy) - -} - -func applicationSetContainer(cr *argoproj.ArgoCD, addSCMGitlabVolumeMount bool) corev1.Container { - // Global proxy env vars go first - appSetEnv := []corev1.EnvVar{{ - Name: "NAMESPACE", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - FieldPath: "metadata.namespace", - }, - }, - }} - - // Merge ApplicationSet env vars provided by the user - // User should be able to override the default NAMESPACE environmental variable - appSetEnv = argoutil.EnvMerge(cr.Spec.ApplicationSet.Env, appSetEnv, true) - // Environment specified in the CR take precedence over everything else - appSetEnv = argoutil.EnvMerge(appSetEnv, proxyEnvVars(), false) - - container := corev1.Container{ - Command: getArgoApplicationSetCommand(cr), - Env: appSetEnv, - Image: getApplicationSetContainerImage(cr), - ImagePullPolicy: corev1.PullAlways, - Name: "argocd-applicationset-controller", - Resources: getApplicationSetResources(cr), - VolumeMounts: []corev1.VolumeMount{ - { - Name: "ssh-known-hosts", - MountPath: "/app/config/ssh", - }, - { - Name: "tls-certs", - MountPath: "/app/config/tls", - }, - { - Name: "gpg-keys", - MountPath: "/app/config/gpg/source", - }, - { - Name: "gpg-keyring", - MountPath: "/app/config/gpg/keys", - }, - { - Name: "tmp", - MountPath: "/tmp", - }, - }, - Ports: []corev1.ContainerPort{ - { - ContainerPort: 7000, - Name: "webhook", - }, - { - ContainerPort: 8080, - Name: "metrics", - }, - }, - SecurityContext: &corev1.SecurityContext{ - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - AllowPrivilegeEscalation: boolPtr(false), - ReadOnlyRootFilesystem: boolPtr(true), - RunAsNonRoot: boolPtr(true), - }, - } - if addSCMGitlabVolumeMount { - container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ - Name: "appset-gitlab-scm-tls-cert", - MountPath: ApplicationSetGitlabSCMTlsCertPath, - }) - } - return container -} - -func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { - - sa := newServiceAccountWithName("applicationset-controller", cr) - setAppSetLabels(&sa.ObjectMeta) - - exists := true - if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { - if !apierrors.IsNotFound(err) { - return nil, err - } - exists = false - } - - if exists { - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - err := r.Client.Delete(context.TODO(), sa) - return nil, err - } - return sa, nil - } - - if err := controllerutil.SetControllerReference(cr, sa, r.Scheme); err != nil { - return nil, err - } - - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - return nil, nil - } - - err := r.Client.Create(context.TODO(), sa) - if err != nil { - return nil, err - } - - return sa, err -} - -func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoproj.ArgoCD) (*rbacv1.Role, error) { - - policyRules := []rbacv1.PolicyRule{ - - // ApplicationSet - { - APIGroups: []string{"argoproj.io"}, - Resources: []string{ - "applications", - "applicationsets", - "appprojects", - "applicationsets/finalizers", - }, - Verbs: []string{ - "create", - "delete", - "get", - "list", - "patch", - "update", - "watch", - }, - }, - // ApplicationSet Status - { - APIGroups: []string{"argoproj.io"}, - Resources: []string{ - "applicationsets/status", - }, - Verbs: []string{ - "get", - "patch", - "update", - }, - }, - - // Events - { - APIGroups: []string{""}, - Resources: []string{ - "events", - }, - Verbs: []string{ - "create", - "delete", - "get", - "list", - "patch", - "update", - "watch", - }, - }, - - // Read Secrets/ConfigMaps - { - APIGroups: []string{""}, - Resources: []string{ - "secrets", - "configmaps", - }, - Verbs: []string{ - "get", - "list", - "watch", - }, - }, - - // Read Deployments - { - APIGroups: []string{"apps", "extensions"}, - Resources: []string{ - "deployments", - }, - Verbs: []string{ - "get", - "list", - "watch", - }, - }, - } - - role := newRole("applicationset-controller", policyRules, cr) - setAppSetLabels(&role.ObjectMeta) - - err := r.Client.Get(context.TODO(), types.NamespacedName{Name: role.Name, Namespace: cr.Namespace}, role) - if err != nil { - if !apierrors.IsNotFound(err) { - return nil, fmt.Errorf("failed to reconcile the role for the service account associated with %s : %s", role.Name, err) - } - if apierrors.IsNotFound(err) && cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - return nil, nil - } - if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { - return nil, err - } - return role, r.Client.Create(context.TODO(), role) - } - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - return nil, r.Client.Delete(context.TODO(), role) - } - - role.Rules = policyRules - if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { - return nil, err - } - return role, r.Client.Update(context.TODO(), role) -} - -func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoproj.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { - - name := "applicationset-controller" - - // get expected name - roleBinding := newRoleBindingWithname(name, cr) - - // fetch existing rolebinding by name - roleBindingExists := true - if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: roleBinding.Name, Namespace: cr.Namespace}, roleBinding); err != nil { - if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to get the rolebinding associated with %s : %s", name, err) - } - if apierrors.IsNotFound(err) && cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - return nil - } - roleBindingExists = false - } - - if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { - return r.Client.Delete(context.TODO(), roleBinding) - } - - setAppSetLabels(&roleBinding.ObjectMeta) - - roleBinding.RoleRef = rbacv1.RoleRef{ - APIGroup: rbacv1.GroupName, - Kind: "Role", - Name: role.Name, - } - - roleBinding.Subjects = []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: sa.Name, - Namespace: sa.Namespace, - }, - } - - if err := controllerutil.SetControllerReference(cr, roleBinding, r.Scheme); err != nil { - return err - } - - if roleBindingExists { - return r.Client.Update(context.TODO(), roleBinding) - } - - return r.Client.Create(context.TODO(), roleBinding) -} - -func getApplicationSetContainerImage(cr *argoproj.ArgoCD) string { - defaultImg, defaultTag := false, false - - img := "" - tag := "" - - // First pull from spec, if it exists - if cr.Spec.ApplicationSet != nil { - img = cr.Spec.ApplicationSet.Image - tag = cr.Spec.ApplicationSet.Version - } - - // If spec is empty, use the defaults - if img == "" { - img = common.ArgoCDDefaultArgoImage - defaultImg = true - } - if tag == "" { - tag = common.ArgoCDDefaultArgoVersion - defaultTag = true - } - - // If an env var is specified then use that, but don't override the spec values (if they are present) - if e := os.Getenv(common.ArgoCDImageEnvName); e != "" && (defaultTag && defaultImg) { - return e - } - return argoutil.CombineImageTag(img, tag) -} - -// getApplicationSetResources will return the ResourceRequirements for the Application Sets container. -func getApplicationSetResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { - resources := corev1.ResourceRequirements{} - - // Allow override of resource requirements from CR - if cr.Spec.ApplicationSet.Resources != nil { - resources = *cr.Spec.ApplicationSet.Resources - } - - return resources -} - -func setAppSetLabels(obj *metav1.ObjectMeta) { - obj.Labels["app.kubernetes.io/name"] = "argocd-applicationset-controller" - obj.Labels["app.kubernetes.io/part-of"] = "argocd-applicationset" - obj.Labels["app.kubernetes.io/component"] = "controller" -} - -// reconcileApplicationSetService will ensure that the Service is present for the ApplicationSet webhook and metrics component. -func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) error { - log.Info("reconciling applicationset service") - - svc := newServiceWithSuffix(common.ApplicationSetServiceNameSuffix, common.ApplicationSetServiceNameSuffix, cr) - if cr.Spec.ApplicationSet == nil || !cr.Spec.ApplicationSet.IsEnabled() { - - if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - err := argoutil.FetchObject(r.Client, cr.Namespace, svc.Name, svc) - if err != nil { - return err - } - log.Info(fmt.Sprintf("Deleting applicationset controller service %s as applicationset is disabled", svc.Name)) - err = r.Delete(context.TODO(), svc) - if err != nil { - return err - } - } - return nil - } else { - if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - return nil // Service found, do nothing - } - } - svc.Spec.Ports = []corev1.ServicePort{ - { - Name: "webhook", - Port: 7000, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(7000), - }, { - Name: "metrics", - Port: 8080, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(8080), - }, - } - - svc.Spec.Selector = map[string]string{ - common.ArgoCDKeyName: nameWithSuffix(common.ApplicationSetServiceNameSuffix, cr), - } - - if err := controllerutil.SetControllerReference(cr, svc, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), svc) -} - // isMergable returns error if any of the extraArgs is already part of the default command Arguments. func isMergable(extraArgs []string, cmd []string) error { if len(extraArgs) > 0 { @@ -2214,3 +576,134 @@ func newRouteWithName(name string, cr *argoproj.ArgoCD) *routev1.Route { func newRouteWithSuffix(suffix string, cr *argoproj.ArgoCD) *routev1.Route { return newRouteWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), cr) } + +// old reconcile function - leave as is +func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { + + reconcileStartTS := time.Now() + defer func() { + ReconcileTime.WithLabelValues(request.Namespace).Observe(time.Since(reconcileStartTS).Seconds()) + }() + + reqLogger := ctrlLog.FromContext(ctx, "namespace", request.Namespace, "name", request.Name) + reqLogger.Info("Reconciling ArgoCD") + + argocd := &argoproj.ArgoCD{} + err := r.Client.Get(ctx, request.NamespacedName, argocd) + if err != nil { + if apierrors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // Fetch labelSelector from r.LabelSelector (command-line option) + labelSelector, err := labels.Parse(r.LabelSelector) + if err != nil { + reqLogger.Info(fmt.Sprintf("error parsing the labelSelector '%s'.", labelSelector)) + return reconcile.Result{}, err + } + // Match the value of labelSelector from ReconcileArgoCD to labels from the argocd instance + if !labelSelector.Matches(labels.Set(argocd.Labels)) { + reqLogger.Info(fmt.Sprintf("the ArgoCD instance '%s' does not match the label selector '%s' and skipping for reconciliation", request.NamespacedName, r.LabelSelector)) + return reconcile.Result{}, fmt.Errorf("Error: failed to reconcile ArgoCD instance: '%s'", request.NamespacedName) + } + + newPhase := argocd.Status.Phase + // If we discover a new Argo CD instance in a previously un-seen namespace + // we add it to the map and increment active instance count by phase + // as well as total active instance count + if _, ok := ActiveInstanceMap[request.Namespace]; !ok { + if newPhase != "" { + ActiveInstanceMap[request.Namespace] = newPhase + ActiveInstancesByPhase.WithLabelValues(newPhase).Inc() + ActiveInstancesTotal.Inc() + } + } else { + // If we discover an existing instance's phase has changed since we last saw it + // increment instance count with new phase and decrement instance count with old phase + // update the phase in corresponding map entry + // total instance count remains the same + if oldPhase := ActiveInstanceMap[argocd.Namespace]; oldPhase != newPhase { + ActiveInstanceMap[argocd.Namespace] = newPhase + ActiveInstancesByPhase.WithLabelValues(newPhase).Inc() + ActiveInstancesByPhase.WithLabelValues(oldPhase).Dec() + } + } + + ActiveInstanceReconciliationCount.WithLabelValues(argocd.Namespace).Inc() + + if argocd.GetDeletionTimestamp() != nil { + + // Argo CD instance marked for deletion; remove entry from activeInstances map and decrement active instance count + // by phase as well as total + delete(ActiveInstanceMap, argocd.Namespace) + ActiveInstancesByPhase.WithLabelValues(newPhase).Dec() + ActiveInstancesTotal.Dec() + ActiveInstanceReconciliationCount.DeleteLabelValues(argocd.Namespace) + ReconcileTime.DeletePartialMatch(prometheus.Labels{"namespace": argocd.Namespace}) + + if argocd.IsDeletionFinalizerPresent() { + if err := r.deleteClusterResources(argocd); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to delete ClusterResources: %w", err) + } + + if isRemoveManagedByLabelOnArgoCDDeletion() { + if err := r.removeManagedByLabelFromNamespaces(argocd.Namespace); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to remove label from namespace[%v], error: %w", argocd.Namespace, err) + } + } + + if err := r.removeUnmanagedSourceNamespaceResources(argocd); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to remove resources from sourceNamespaces, error: %w", err) + } + + if err := r.removeDeletionFinalizer(argocd); err != nil { + return reconcile.Result{}, err + } + + // remove namespace of deleted Argo CD instance from deprecationEventEmissionTracker (if exists) so that if another instance + // is created in the same namespace in the future, that instance is appropriately tracked + delete(DeprecationEventEmissionTracker, argocd.Namespace) + } + return reconcile.Result{}, nil + } + + if !argocd.IsDeletionFinalizerPresent() { + if err := r.addDeletionFinalizer(argocd); err != nil { + return reconcile.Result{}, err + } + } + + // get the latest version of argocd instance before reconciling + if err = r.Client.Get(ctx, request.NamespacedName, argocd); err != nil { + return reconcile.Result{}, err + } + + if err = r.setManagedNamespaces(argocd); err != nil { + return reconcile.Result{}, err + } + + if err = r.setManagedSourceNamespaces(argocd); err != nil { + return reconcile.Result{}, err + } + + if err := r.reconcileResources(argocd); err != nil { + // Error reconciling ArgoCD sub-resources - requeue the request. + return reconcile.Result{}, err + } + + // Return and don't requeue + return reconcile.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *ReconcileArgoCD) SetupWithManager(mgr ctrl.Manager) error { + bldr := ctrl.NewControllerManagedBy(mgr) + r.setResourceWatches(bldr, r.clusterResourceMapper, r.tlsSecretMapper, r.namespaceResourceMapper, r.clusterSecretResourceMapper, r.applicationSetSCMTLSConfigMapMapper) + return bldr.Complete(r) +} diff --git a/controllers/argocd/appcontroller_TOBEREMOVED.go b/controllers/argocd/appcontroller_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/appcontroller_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/appset_TOBEREMOVED.go b/controllers/argocd/appset_TOBEREMOVED.go new file mode 100644 index 000000000..c80192954 --- /dev/null +++ b/controllers/argocd/appset_TOBEREMOVED.go @@ -0,0 +1,577 @@ +package argocd + +import ( + "context" + "fmt" + "os" + "reflect" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +const ( + ApplicationSetGitlabSCMTlsCertPath = "/app/tls/scm/cert" +) + +// getArgoApplicationSetCommand will return the command for the ArgoCD ApplicationSet component. +func getArgoApplicationSetCommand(cr *argoproj.ArgoCD) []string { + cmd := make([]string, 0) + + cmd = append(cmd, "entrypoint.sh") + cmd = append(cmd, "argocd-applicationset-controller") + + if cr.Spec.Repo.IsEnabled() { + cmd = append(cmd, "--argocd-repo-server", getRepoServerAddress(cr)) + } else { + log.Info("Repo Server is disabled. This would affect the functioning of ApplicationSet Controller.") + } + + cmd = append(cmd, "--loglevel") + cmd = append(cmd, getLogLevel(cr.Spec.ApplicationSet.LogLevel)) + + if cr.Spec.ApplicationSet.SCMRootCAConfigMap != "" { + cmd = append(cmd, "--scm-root-ca-path") + cmd = append(cmd, ApplicationSetGitlabSCMTlsCertPath) + } + + // ApplicationSet command arguments provided by the user + extraArgs := cr.Spec.ApplicationSet.ExtraCommandArgs + err := isMergable(extraArgs, cmd) + if err != nil { + return cmd + } + + cmd = append(cmd, extraArgs...) + + return cmd +} + +func (r *ReconcileArgoCD) reconcileApplicationSetController(cr *argoproj.ArgoCD) error { + + log.Info("reconciling applicationset serviceaccounts") + sa, err := r.reconcileApplicationSetServiceAccount(cr) + if err != nil { + return err + } + + log.Info("reconciling applicationset roles") + role, err := r.reconcileApplicationSetRole(cr) + if err != nil { + return err + } + + log.Info("reconciling applicationset role bindings") + if err := r.reconcileApplicationSetRoleBinding(cr, role, sa); err != nil { + return err + } + + log.Info("reconciling applicationset deployments") + if err := r.reconcileApplicationSetDeployment(cr, sa); err != nil { + return err + } + + log.Info("reconciling applicationset service") + if err := r.reconcileApplicationSetService(cr); err != nil { + return err + } + + return nil +} + +// reconcileApplicationControllerDeployment will ensure the Deployment resource is present for the ArgoCD Application Controller component. +func (r *ReconcileArgoCD) reconcileApplicationSetDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { + deploy := newDeploymentWithSuffix("applicationset-controller", "controller", cr) + + setAppSetLabels(&deploy.ObjectMeta) + + podSpec := &deploy.Spec.Template.Spec + + // sa would be nil when spec.applicationset.enabled = false + if sa != nil { + podSpec.ServiceAccountName = sa.ObjectMeta.Name + } + podSpec.Volumes = []corev1.Volume{ + { + Name: "ssh-known-hosts", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDKnownHostsConfigMapName, + }, + }, + }, + }, + { + Name: "tls-certs", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDTLSCertsConfigMapName, + }, + }, + }, + }, + { + Name: "gpg-keys", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDGPGKeysConfigMapName, + }, + }, + }, + }, + { + Name: "gpg-keyring", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "tmp", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + } + addSCMGitlabVolumeMount := false + if scmRootCAConfigMapName := getSCMRootCAConfigMapName(cr); scmRootCAConfigMapName != "" { + cm := newConfigMapWithName(scmRootCAConfigMapName, cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, cr.Spec.ApplicationSet.SCMRootCAConfigMap, cm) { + addSCMGitlabVolumeMount = true + podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{ + Name: "appset-gitlab-scm-tls-cert", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDAppSetGitlabSCMTLSCertsConfigMapName, + }, + }, + }, + }) + } + } + + podSpec.Containers = []corev1.Container{ + applicationSetContainer(cr, addSCMGitlabVolumeMount), + } + AddSeccompProfileForOpenShift(r.Client, podSpec) + + if existing := newDeploymentWithSuffix("applicationset-controller", "controller", cr); argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + err := r.Client.Delete(context.TODO(), existing) + return err + } + + existingSpec := existing.Spec.Template.Spec + + deploymentsDifferent := !reflect.DeepEqual(existingSpec.Containers[0], podSpec.Containers) || + !reflect.DeepEqual(existingSpec.Volumes, podSpec.Volumes) || + existingSpec.ServiceAccountName != podSpec.ServiceAccountName || + !reflect.DeepEqual(existing.Labels, deploy.Labels) || + !reflect.DeepEqual(existing.Spec.Template.Labels, deploy.Spec.Template.Labels) || + !reflect.DeepEqual(existing.Spec.Selector, deploy.Spec.Selector) || + !reflect.DeepEqual(existing.Spec.Template.Spec.NodeSelector, deploy.Spec.Template.Spec.NodeSelector) || + !reflect.DeepEqual(existing.Spec.Template.Spec.Tolerations, deploy.Spec.Template.Spec.Tolerations) + + // If the Deployment already exists, make sure the values we care about are up-to-date + if deploymentsDifferent { + existing.Spec.Template.Spec.Containers = podSpec.Containers + existing.Spec.Template.Spec.Volumes = podSpec.Volumes + existing.Spec.Template.Spec.ServiceAccountName = podSpec.ServiceAccountName + existing.Labels = deploy.Labels + existing.Spec.Template.Labels = deploy.Spec.Template.Labels + existing.Spec.Selector = deploy.Spec.Selector + existing.Spec.Template.Spec.NodeSelector = deploy.Spec.Template.Spec.NodeSelector + existing.Spec.Template.Spec.Tolerations = deploy.Spec.Template.Spec.Tolerations + return r.Client.Update(context.TODO(), existing) + } + return nil // Deployment found with nothing to do, move along... + } + + if !cr.Spec.ApplicationSet.IsEnabled() { + return nil + } + + if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), deploy) + +} + +func applicationSetContainer(cr *argoproj.ArgoCD, addSCMGitlabVolumeMount bool) corev1.Container { + // Global proxy env vars go first + appSetEnv := []corev1.EnvVar{{ + Name: "NAMESPACE", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.namespace", + }, + }, + }} + + // Merge ApplicationSet env vars provided by the user + // User should be able to override the default NAMESPACE environmental variable + appSetEnv = argoutil.EnvMerge(cr.Spec.ApplicationSet.Env, appSetEnv, true) + // Environment specified in the CR take precedence over everything else + appSetEnv = argoutil.EnvMerge(appSetEnv, proxyEnvVars(), false) + + container := corev1.Container{ + Command: getArgoApplicationSetCommand(cr), + Env: appSetEnv, + Image: getApplicationSetContainerImage(cr), + ImagePullPolicy: corev1.PullAlways, + Name: "argocd-applicationset-controller", + Resources: getApplicationSetResources(cr), + VolumeMounts: []corev1.VolumeMount{ + { + Name: "ssh-known-hosts", + MountPath: "/app/config/ssh", + }, + { + Name: "tls-certs", + MountPath: "/app/config/tls", + }, + { + Name: "gpg-keys", + MountPath: "/app/config/gpg/source", + }, + { + Name: "gpg-keyring", + MountPath: "/app/config/gpg/keys", + }, + { + Name: "tmp", + MountPath: "/tmp", + }, + }, + Ports: []corev1.ContainerPort{ + { + ContainerPort: 7000, + Name: "webhook", + }, + { + ContainerPort: 8080, + Name: "metrics", + }, + }, + SecurityContext: &corev1.SecurityContext{ + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + AllowPrivilegeEscalation: boolPtr(false), + ReadOnlyRootFilesystem: boolPtr(true), + RunAsNonRoot: boolPtr(true), + }, + } + if addSCMGitlabVolumeMount { + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: "appset-gitlab-scm-tls-cert", + MountPath: ApplicationSetGitlabSCMTlsCertPath, + }) + } + return container +} + +func (r *ReconcileArgoCD) reconcileApplicationSetServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { + + sa := newServiceAccountWithName("applicationset-controller", cr) + setAppSetLabels(&sa.ObjectMeta) + + exists := true + if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { + if !apierrors.IsNotFound(err) { + return nil, err + } + exists = false + } + + if exists { + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + err := r.Client.Delete(context.TODO(), sa) + return nil, err + } + return sa, nil + } + + if err := controllerutil.SetControllerReference(cr, sa, r.Scheme); err != nil { + return nil, err + } + + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil, nil + } + + err := r.Client.Create(context.TODO(), sa) + if err != nil { + return nil, err + } + + return sa, err +} + +func (r *ReconcileArgoCD) reconcileApplicationSetRole(cr *argoproj.ArgoCD) (*rbacv1.Role, error) { + + policyRules := []rbacv1.PolicyRule{ + + // ApplicationSet + { + APIGroups: []string{"argoproj.io"}, + Resources: []string{ + "applications", + "applicationsets", + "appprojects", + "applicationsets/finalizers", + }, + Verbs: []string{ + "create", + "delete", + "get", + "list", + "patch", + "update", + "watch", + }, + }, + // ApplicationSet Status + { + APIGroups: []string{"argoproj.io"}, + Resources: []string{ + "applicationsets/status", + }, + Verbs: []string{ + "get", + "patch", + "update", + }, + }, + + // Events + { + APIGroups: []string{""}, + Resources: []string{ + "events", + }, + Verbs: []string{ + "create", + "delete", + "get", + "list", + "patch", + "update", + "watch", + }, + }, + + // Read Secrets/ConfigMaps + { + APIGroups: []string{""}, + Resources: []string{ + "secrets", + "configmaps", + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + + // Read Deployments + { + APIGroups: []string{"apps", "extensions"}, + Resources: []string{ + "deployments", + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + } + + role := newRole("applicationset-controller", policyRules, cr) + setAppSetLabels(&role.ObjectMeta) + + err := r.Client.Get(context.TODO(), types.NamespacedName{Name: role.Name, Namespace: cr.Namespace}, role) + if err != nil { + if !apierrors.IsNotFound(err) { + return nil, fmt.Errorf("failed to reconcile the role for the service account associated with %s : %s", role.Name, err) + } + if apierrors.IsNotFound(err) && cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil, nil + } + if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { + return nil, err + } + return role, r.Client.Create(context.TODO(), role) + } + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil, r.Client.Delete(context.TODO(), role) + } + + role.Rules = policyRules + if err = controllerutil.SetControllerReference(cr, role, r.Scheme); err != nil { + return nil, err + } + return role, r.Client.Update(context.TODO(), role) +} + +func (r *ReconcileArgoCD) reconcileApplicationSetRoleBinding(cr *argoproj.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { + + name := "applicationset-controller" + + // get expected name + roleBinding := newRoleBindingWithname(name, cr) + + // fetch existing rolebinding by name + roleBindingExists := true + if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: roleBinding.Name, Namespace: cr.Namespace}, roleBinding); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get the rolebinding associated with %s : %s", name, err) + } + if apierrors.IsNotFound(err) && cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return nil + } + roleBindingExists = false + } + + if cr.Spec.ApplicationSet != nil && !cr.Spec.ApplicationSet.IsEnabled() { + return r.Client.Delete(context.TODO(), roleBinding) + } + + setAppSetLabels(&roleBinding.ObjectMeta) + + roleBinding.RoleRef = rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: role.Name, + } + + roleBinding.Subjects = []rbacv1.Subject{ + { + Kind: rbacv1.ServiceAccountKind, + Name: sa.Name, + Namespace: sa.Namespace, + }, + } + + if err := controllerutil.SetControllerReference(cr, roleBinding, r.Scheme); err != nil { + return err + } + + if roleBindingExists { + return r.Client.Update(context.TODO(), roleBinding) + } + + return r.Client.Create(context.TODO(), roleBinding) +} + +func getApplicationSetContainerImage(cr *argoproj.ArgoCD) string { + defaultImg, defaultTag := false, false + + img := "" + tag := "" + + // First pull from spec, if it exists + if cr.Spec.ApplicationSet != nil { + img = cr.Spec.ApplicationSet.Image + tag = cr.Spec.ApplicationSet.Version + } + + // If spec is empty, use the defaults + if img == "" { + img = common.ArgoCDDefaultArgoImage + defaultImg = true + } + if tag == "" { + tag = common.ArgoCDDefaultArgoVersion + defaultTag = true + } + + // If an env var is specified then use that, but don't override the spec values (if they are present) + if e := os.Getenv(common.ArgoCDImageEnvName); e != "" && (defaultTag && defaultImg) { + return e + } + return argoutil.CombineImageTag(img, tag) +} + +// getApplicationSetResources will return the ResourceRequirements for the Application Sets container. +func getApplicationSetResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { + resources := corev1.ResourceRequirements{} + + // Allow override of resource requirements from CR + if cr.Spec.ApplicationSet.Resources != nil { + resources = *cr.Spec.ApplicationSet.Resources + } + + return resources +} + +func setAppSetLabels(obj *metav1.ObjectMeta) { + obj.Labels["app.kubernetes.io/name"] = "argocd-applicationset-controller" + obj.Labels["app.kubernetes.io/part-of"] = "argocd-applicationset" + obj.Labels["app.kubernetes.io/component"] = "controller" +} + +// reconcileApplicationSetService will ensure that the Service is present for the ApplicationSet webhook and metrics component. +func (r *ReconcileArgoCD) reconcileApplicationSetService(cr *argoproj.ArgoCD) error { + log.Info("reconciling applicationset service") + + svc := newServiceWithSuffix(common.ApplicationSetServiceNameSuffix, common.ApplicationSetServiceNameSuffix, cr) + if cr.Spec.ApplicationSet == nil || !cr.Spec.ApplicationSet.IsEnabled() { + + if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + err := argoutil.FetchObject(r.Client, cr.Namespace, svc.Name, svc) + if err != nil { + return err + } + log.Info(fmt.Sprintf("Deleting applicationset controller service %s as applicationset is disabled", svc.Name)) + err = r.Delete(context.TODO(), svc) + if err != nil { + return err + } + } + return nil + } else { + if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + return nil // Service found, do nothing + } + } + svc.Spec.Ports = []corev1.ServicePort{ + { + Name: "webhook", + Port: 7000, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(7000), + }, { + Name: "metrics", + Port: 8080, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(8080), + }, + } + + svc.Spec.Selector = map[string]string{ + common.ArgoCDKeyName: nameWithSuffix(common.ApplicationSetServiceNameSuffix, cr), + } + + if err := controllerutil.SetControllerReference(cr, svc, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), svc) +} diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 476555542..2b9e7d4de 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -24,7 +24,6 @@ import ( monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" oappsv1 "github.com/openshift/api/apps/v1" routev1 "github.com/openshift/api/route/v1" - "github.com/prometheus/client_golang/prometheus" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" @@ -47,14 +46,12 @@ import ( networkingv1 "k8s.io/api/networking/v1" v1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" - ctrlLog "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -239,130 +236,6 @@ func (r *ArgoCDReconciler) Reconcile(ctx context.Context, request ctrl.Request) return reconcile.Result{}, nil } -// old reconcile function - leave as is -func (r *ReconcileArgoCD) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { - - reconcileStartTS := time.Now() - defer func() { - ReconcileTime.WithLabelValues(request.Namespace).Observe(time.Since(reconcileStartTS).Seconds()) - }() - - reqLogger := ctrlLog.FromContext(ctx, "namespace", request.Namespace, "name", request.Name) - reqLogger.Info("Reconciling ArgoCD") - - argocd := &argoproj.ArgoCD{} - err := r.Client.Get(ctx, request.NamespacedName, argocd) - if err != nil { - if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. - // Return and don't requeue - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - // Fetch labelSelector from r.LabelSelector (command-line option) - labelSelector, err := labels.Parse(r.LabelSelector) - if err != nil { - reqLogger.Info(fmt.Sprintf("error parsing the labelSelector '%s'.", labelSelector)) - return reconcile.Result{}, err - } - // Match the value of labelSelector from ReconcileArgoCD to labels from the argocd instance - if !labelSelector.Matches(labels.Set(argocd.Labels)) { - reqLogger.Info(fmt.Sprintf("the ArgoCD instance '%s' does not match the label selector '%s' and skipping for reconciliation", request.NamespacedName, r.LabelSelector)) - return reconcile.Result{}, fmt.Errorf("Error: failed to reconcile ArgoCD instance: '%s'", request.NamespacedName) - } - - newPhase := argocd.Status.Phase - // If we discover a new Argo CD instance in a previously un-seen namespace - // we add it to the map and increment active instance count by phase - // as well as total active instance count - if _, ok := ActiveInstanceMap[request.Namespace]; !ok { - if newPhase != "" { - ActiveInstanceMap[request.Namespace] = newPhase - ActiveInstancesByPhase.WithLabelValues(newPhase).Inc() - ActiveInstancesTotal.Inc() - } - } else { - // If we discover an existing instance's phase has changed since we last saw it - // increment instance count with new phase and decrement instance count with old phase - // update the phase in corresponding map entry - // total instance count remains the same - if oldPhase := ActiveInstanceMap[argocd.Namespace]; oldPhase != newPhase { - ActiveInstanceMap[argocd.Namespace] = newPhase - ActiveInstancesByPhase.WithLabelValues(newPhase).Inc() - ActiveInstancesByPhase.WithLabelValues(oldPhase).Dec() - } - } - - ActiveInstanceReconciliationCount.WithLabelValues(argocd.Namespace).Inc() - - if argocd.GetDeletionTimestamp() != nil { - - // Argo CD instance marked for deletion; remove entry from activeInstances map and decrement active instance count - // by phase as well as total - delete(ActiveInstanceMap, argocd.Namespace) - ActiveInstancesByPhase.WithLabelValues(newPhase).Dec() - ActiveInstancesTotal.Dec() - ActiveInstanceReconciliationCount.DeleteLabelValues(argocd.Namespace) - ReconcileTime.DeletePartialMatch(prometheus.Labels{"namespace": argocd.Namespace}) - - if argocd.IsDeletionFinalizerPresent() { - if err := r.deleteClusterResources(argocd); err != nil { - return reconcile.Result{}, fmt.Errorf("failed to delete ClusterResources: %w", err) - } - - if isRemoveManagedByLabelOnArgoCDDeletion() { - if err := r.removeManagedByLabelFromNamespaces(argocd.Namespace); err != nil { - return reconcile.Result{}, fmt.Errorf("failed to remove label from namespace[%v], error: %w", argocd.Namespace, err) - } - } - - if err := r.removeUnmanagedSourceNamespaceResources(argocd); err != nil { - return reconcile.Result{}, fmt.Errorf("failed to remove resources from sourceNamespaces, error: %w", err) - } - - if err := r.removeDeletionFinalizer(argocd); err != nil { - return reconcile.Result{}, err - } - - // remove namespace of deleted Argo CD instance from deprecationEventEmissionTracker (if exists) so that if another instance - // is created in the same namespace in the future, that instance is appropriately tracked - delete(DeprecationEventEmissionTracker, argocd.Namespace) - } - return reconcile.Result{}, nil - } - - if !argocd.IsDeletionFinalizerPresent() { - if err := r.addDeletionFinalizer(argocd); err != nil { - return reconcile.Result{}, err - } - } - - // get the latest version of argocd instance before reconciling - if err = r.Client.Get(ctx, request.NamespacedName, argocd); err != nil { - return reconcile.Result{}, err - } - - if err = r.setManagedNamespaces(argocd); err != nil { - return reconcile.Result{}, err - } - - if err = r.setManagedSourceNamespaces(argocd); err != nil { - return reconcile.Result{}, err - } - - if err := r.reconcileResources(argocd); err != nil { - // Error reconciling ArgoCD sub-resources - requeue the request. - return reconcile.Result{}, err - } - - // Return and don't requeue - return reconcile.Result{}, nil -} - // setResourceManagedNamespaces finds all namespaces carrying the managed-by label, adds the control plane namespace and stores that list in ArgoCDReconciler to be accessed later func (r *ArgoCDReconciler) setResourceManagedNamespaces() error { r.ResourceManagedNamespaces = make(map[string]string) @@ -635,13 +508,6 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { } -// SetupWithManager sets up the controller with the Manager. -func (r *ReconcileArgoCD) SetupWithManager(mgr ctrl.Manager) error { - bldr := ctrl.NewControllerManagedBy(mgr) - r.setResourceWatches(bldr, r.clusterResourceMapper, r.tlsSecretMapper, r.namespaceResourceMapper, r.clusterSecretResourceMapper, r.applicationSetSCMTLSConfigMapMapper) - return bldr.Complete(r) -} - // SetupWithManager sets up the controller with the Manager. func (r *ArgoCDReconciler) SetupWithManager(mgr ctrl.Manager) error { bldr := ctrl.NewControllerManagedBy(mgr) diff --git a/controllers/argocd/cm_TOBEREMOVED.go b/controllers/argocd/cm_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/cm_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/dex_TOBEREMOVED.go b/controllers/argocd/dex_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/dex_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/keycloak_TOBEREMOVED.go b/controllers/argocd/keycloak_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/keycloak_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/notifications_TOBEREMOVED.go b/controllers/argocd/notifications_TOBEREMOVED.go new file mode 100644 index 000000000..0decc742f --- /dev/null +++ b/controllers/argocd/notifications_TOBEREMOVED.go @@ -0,0 +1,1098 @@ +package argocd + +import ( + "context" + "fmt" + "reflect" + "time" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +// getNotificationsResources will return the ResourceRequirements for the Notifications container. +func getNotificationsResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { + resources := corev1.ResourceRequirements{} + + // Allow override of resource requirements from CR + if cr.Spec.Notifications.Resources != nil { + resources = *cr.Spec.Notifications.Resources + } + + return resources +} + +func getNotificationsCommand(cr *argoproj.ArgoCD) []string { + + cmd := make([]string, 0) + cmd = append(cmd, "argocd-notifications") + + cmd = append(cmd, "--loglevel") + cmd = append(cmd, getLogLevel(cr.Spec.Notifications.LogLevel)) + + return cmd +} + +// reconcileNotificationsConfigMap only creates/deletes the argocd-notifications-cm based on whether notifications is enabled/disabled in the CR +// It does not reconcile/overwrite any fields or information in the configmap itself +func (r *ReconcileArgoCD) reconcileNotificationsConfigMap(cr *argoproj.ArgoCD) error { + + desiredConfigMap := newConfigMapWithName("argocd-notifications-cm", cr) + desiredConfigMap.Data = getDefaultNotificationsConfig() + + cmExists := true + existingConfigMap := &corev1.ConfigMap{} + if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredConfigMap.Name, existingConfigMap); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get the configmap associated with %s : %s", desiredConfigMap.Name, err) + } + cmExists = false + } + + if cmExists { + // CM exists but shouldn't, so it should be deleted + if !cr.Spec.Notifications.Enabled { + log.Info(fmt.Sprintf("Deleting configmap %s as notifications is disabled", existingConfigMap.Name)) + return r.Client.Delete(context.TODO(), existingConfigMap) + } + + // CM exists and should, nothing to do here + return nil + } + + // CM doesn't exist and shouldn't, nothing to do here + if !cr.Spec.Notifications.Enabled { + return nil + } + + // CM doesn't exist but should, so it should be created + if err := controllerutil.SetControllerReference(cr, desiredConfigMap, r.Scheme); err != nil { + return err + } + + log.Info(fmt.Sprintf("Creating configmap %s", desiredConfigMap.Name)) + err := r.Client.Create(context.TODO(), desiredConfigMap) + if err != nil { + return err + } + + return nil +} + +// reconcileNotificationsSecret only creates/deletes the argocd-notifications-secret based on whether notifications is enabled/disabled in the CR +// It does not reconcile/overwrite any fields or information in the secret itself +func (r *ReconcileArgoCD) reconcileNotificationsSecret(cr *argoproj.ArgoCD) error { + + desiredSecret := argoutil.NewSecretWithName(cr, "argocd-notifications-secret") + + secretExists := true + existingSecret := &corev1.Secret{} + if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredSecret.Name, existingSecret); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get the secret associated with %s : %s", desiredSecret.Name, err) + } + secretExists = false + } + + if secretExists { + // secret exists but shouldn't, so it should be deleted + if !cr.Spec.Notifications.Enabled { + log.Info(fmt.Sprintf("Deleting secret %s as notifications is disabled", existingSecret.Name)) + return r.Client.Delete(context.TODO(), existingSecret) + } + + // secret exists and should, nothing to do here + return nil + } + + // secret doesn't exist and shouldn't, nothing to do here + if !cr.Spec.Notifications.Enabled { + return nil + } + + // secret doesn't exist but should, so it should be created + if err := controllerutil.SetControllerReference(cr, desiredSecret, r.Scheme); err != nil { + return err + } + + log.Info(fmt.Sprintf("Creating secret %s", desiredSecret.Name)) + err := r.Client.Create(context.TODO(), desiredSecret) + if err != nil { + return err + } + + return nil +} + +func (r *ReconcileArgoCD) reconcileNotificationsController(cr *argoproj.ArgoCD) error { + + log.Info("reconciling notifications serviceaccount") + sa, err := r.reconcileNotificationsServiceAccount(cr) + if err != nil { + return err + } + + log.Info("reconciling notifications role") + role, err := r.reconcileNotificationsRole(cr) + if err != nil { + return err + } + + log.Info("reconciling notifications role binding") + if err := r.reconcileNotificationsRoleBinding(cr, role, sa); err != nil { + return err + } + + log.Info("reconciling notifications configmap") + if err := r.reconcileNotificationsConfigMap(cr); err != nil { + return err + } + + log.Info("reconciling notifications secret") + if err := r.reconcileNotificationsSecret(cr); err != nil { + return err + } + + log.Info("reconciling notifications deployment") + if err := r.reconcileNotificationsDeployment(cr, sa); err != nil { + return err + } + + return nil +} + +// The code to create/delete notifications resources is written within the reconciliation logic itself. However, these functions must be called +// in the right order depending on whether resources are getting created or deleted. During creation we must create the role and sa first. +// RoleBinding and deployment are dependent on these resouces. During deletion the order is reversed. +// Deployment and RoleBinding must be deleted before the role and sa. deleteNotificationsResources will only be called during +// delete events, so we don't need to worry about duplicate, recurring reconciliation calls +func (r *ReconcileArgoCD) deleteNotificationsResources(cr *argoproj.ArgoCD) error { + + sa := &corev1.ServiceAccount{} + role := &rbacv1.Role{} + + if err := argoutil.FetchObject(r.Client, cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDNotificationsControllerComponent), sa); err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } + if err := argoutil.FetchObject(r.Client, cr.Namespace, fmt.Sprintf("%s-%s", cr.Name, common.ArgoCDNotificationsControllerComponent), role); err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } + + log.Info("reconciling notifications deployment") + if err := r.reconcileNotificationsDeployment(cr, sa); err != nil { + return err + } + + log.Info("reconciling notifications secret") + if err := r.reconcileNotificationsSecret(cr); err != nil { + return err + } + + log.Info("reconciling notifications configmap") + if err := r.reconcileNotificationsConfigMap(cr); err != nil { + return err + } + + log.Info("reconciling notifications role binding") + if err := r.reconcileNotificationsRoleBinding(cr, role, sa); err != nil { + return err + } + + log.Info("reconciling notifications role") + _, err := r.reconcileNotificationsRole(cr) + if err != nil { + return err + } + + log.Info("reconciling notifications serviceaccount") + _, err = r.reconcileNotificationsServiceAccount(cr) + if err != nil { + return err + } + + return nil +} + +func (r *ReconcileArgoCD) reconcileNotificationsServiceAccount(cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { + + sa := newServiceAccountWithName(common.ArgoCDNotificationsControllerComponent, cr) + + if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { + if !apierrors.IsNotFound(err) { + return nil, fmt.Errorf("failed to get the serviceAccount associated with %s : %s", sa.Name, err) + } + + // SA doesn't exist and shouldn't, nothing to do here + if !cr.Spec.Notifications.Enabled { + return nil, nil + } + + // SA doesn't exist but should, so it should be created + if err := controllerutil.SetControllerReference(cr, sa, r.Scheme); err != nil { + return nil, err + } + + log.Info(fmt.Sprintf("Creating serviceaccount %s", sa.Name)) + err := r.Client.Create(context.TODO(), sa) + if err != nil { + return nil, err + } + } + + // SA exists but shouldn't, so it should be deleted + if !cr.Spec.Notifications.Enabled { + log.Info(fmt.Sprintf("Deleting serviceaccount %s as notifications is disabled", sa.Name)) + return nil, r.Client.Delete(context.TODO(), sa) + } + + return sa, nil +} + +func (r *ReconcileArgoCD) reconcileNotificationsRole(cr *argoproj.ArgoCD) (*rbacv1.Role, error) { + + policyRules := policyRuleForNotificationsController() + desiredRole := newRole(common.ArgoCDNotificationsControllerComponent, policyRules, cr) + + existingRole := &rbacv1.Role{} + if err := argoutil.FetchObject(r.Client, cr.Namespace, desiredRole.Name, existingRole); err != nil { + if !apierrors.IsNotFound(err) { + return nil, fmt.Errorf("failed to get the role associated with %s : %s", desiredRole.Name, err) + } + + // role does not exist and shouldn't, nothing to do here + if !cr.Spec.Notifications.Enabled { + return nil, nil + } + + // role does not exist but should, so it should be created + if err := controllerutil.SetControllerReference(cr, desiredRole, r.Scheme); err != nil { + return nil, err + } + + log.Info(fmt.Sprintf("Creating role %s", desiredRole.Name)) + err := r.Client.Create(context.TODO(), desiredRole) + if err != nil { + return nil, err + } + return desiredRole, nil + } + + // role exists but shouldn't, so it should be deleted + if !cr.Spec.Notifications.Enabled { + log.Info(fmt.Sprintf("Deleting role %s as notifications is disabled", existingRole.Name)) + return nil, r.Client.Delete(context.TODO(), existingRole) + } + + // role exists and should. Reconcile role if changed + if !reflect.DeepEqual(existingRole.Rules, desiredRole.Rules) { + existingRole.Rules = desiredRole.Rules + if err := controllerutil.SetControllerReference(cr, existingRole, r.Scheme); err != nil { + return nil, err + } + return existingRole, r.Client.Update(context.TODO(), existingRole) + } + + return desiredRole, nil +} + +func (r *ReconcileArgoCD) reconcileNotificationsRoleBinding(cr *argoproj.ArgoCD, role *rbacv1.Role, sa *corev1.ServiceAccount) error { + + desiredRoleBinding := newRoleBindingWithname(common.ArgoCDNotificationsControllerComponent, cr) + desiredRoleBinding.RoleRef = rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: role.Name, + } + + desiredRoleBinding.Subjects = []rbacv1.Subject{ + { + Kind: rbacv1.ServiceAccountKind, + Name: sa.Name, + Namespace: sa.Namespace, + }, + } + + // fetch existing rolebinding by name + existingRoleBinding := &rbacv1.RoleBinding{} + if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: desiredRoleBinding.Name, Namespace: cr.Namespace}, existingRoleBinding); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get the rolebinding associated with %s : %s", desiredRoleBinding.Name, err) + } + + // roleBinding does not exist and shouldn't, nothing to do here + if !cr.Spec.Notifications.Enabled { + return nil + } + + // roleBinding does not exist but should, so it should be created + if err := controllerutil.SetControllerReference(cr, desiredRoleBinding, r.Scheme); err != nil { + return err + } + + log.Info(fmt.Sprintf("Creating roleBinding %s", desiredRoleBinding.Name)) + return r.Client.Create(context.TODO(), desiredRoleBinding) + } + + // roleBinding exists but shouldn't, so it should be deleted + if !cr.Spec.Notifications.Enabled { + log.Info(fmt.Sprintf("Deleting roleBinding %s as notifications is disabled", existingRoleBinding.Name)) + return r.Client.Delete(context.TODO(), existingRoleBinding) + } + + // roleBinding exists and should. Reconcile roleBinding if changed + if !reflect.DeepEqual(existingRoleBinding.RoleRef, desiredRoleBinding.RoleRef) { + // if the RoleRef changes, delete the existing role binding and create a new one + if err := r.Client.Delete(context.TODO(), existingRoleBinding); err != nil { + return err + } + } else if !reflect.DeepEqual(existingRoleBinding.Subjects, desiredRoleBinding.Subjects) { + existingRoleBinding.Subjects = desiredRoleBinding.Subjects + if err := controllerutil.SetControllerReference(cr, existingRoleBinding, r.Scheme); err != nil { + return err + } + return r.Client.Update(context.TODO(), existingRoleBinding) + } + + return nil +} + +func (r *ReconcileArgoCD) reconcileNotificationsDeployment(cr *argoproj.ArgoCD, sa *corev1.ServiceAccount) error { + + desiredDeployment := newDeploymentWithSuffix("notifications-controller", "controller", cr) + + desiredDeployment.Spec.Strategy = appsv1.DeploymentStrategy{ + Type: appsv1.RecreateDeploymentStrategyType, + } + + if replicas := getArgoCDNotificationsControllerReplicas(cr); replicas != nil { + desiredDeployment.Spec.Replicas = replicas + } + + notificationEnv := cr.Spec.Notifications.Env + // Let user specify their own environment first + notificationEnv = argoutil.EnvMerge(notificationEnv, proxyEnvVars(), false) + + podSpec := &desiredDeployment.Spec.Template.Spec + podSpec.SecurityContext = &corev1.PodSecurityContext{ + RunAsNonRoot: boolPtr(true), + } + AddSeccompProfileForOpenShift(r.Client, podSpec) + podSpec.ServiceAccountName = sa.ObjectMeta.Name + podSpec.Volumes = []corev1.Volume{ + { + Name: "tls-certs", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDTLSCertsConfigMapName, + }, + }, + }, + }, + { + Name: "argocd-repo-server-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRepoServerTLSSecretName, + Optional: boolPtr(true), + }, + }, + }, + } + + podSpec.Containers = []corev1.Container{{ + Command: getNotificationsCommand(cr), + Image: getArgoContainerImage(cr), + ImagePullPolicy: corev1.PullAlways, + Name: common.ArgoCDNotificationsControllerComponent, + Env: notificationEnv, + Resources: getNotificationsResources(cr), + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.IntOrString{ + IntVal: int32(9001), + }, + }, + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "tls-certs", + MountPath: "/app/config/tls", + }, + { + Name: "argocd-repo-server-tls", + MountPath: "/app/config/reposerver/tls", + }, + }, + WorkingDir: "/app", + }} + + // fetch existing deployment by name + deploymentChanged := false + existingDeployment := &appsv1.Deployment{} + if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: desiredDeployment.Name, Namespace: cr.Namespace}, existingDeployment); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get the deployment associated with %s : %s", existingDeployment.Name, err) + } + + // deployment does not exist and shouldn't, nothing to do here + if !cr.Spec.Notifications.Enabled { + return nil + } + + // deployment does not exist but should, so it should be created + if err := controllerutil.SetControllerReference(cr, desiredDeployment, r.Scheme); err != nil { + return err + } + + log.Info(fmt.Sprintf("Creating deployment %s", desiredDeployment.Name)) + return r.Client.Create(context.TODO(), desiredDeployment) + } + + // deployment exists but shouldn't, so it should be deleted + if !cr.Spec.Notifications.Enabled { + log.Info(fmt.Sprintf("Deleting deployment %s as notifications is disabled", existingDeployment.Name)) + return r.Client.Delete(context.TODO(), existingDeployment) + } + + // deployment exists and should. Reconcile deployment if changed + updateNodePlacement(existingDeployment, desiredDeployment, &deploymentChanged) + + if existingDeployment.Spec.Template.Spec.Containers[0].Image != desiredDeployment.Spec.Template.Spec.Containers[0].Image { + existingDeployment.Spec.Template.Spec.Containers[0].Image = desiredDeployment.Spec.Template.Spec.Containers[0].Image + existingDeployment.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Command, desiredDeployment.Spec.Template.Spec.Containers[0].Command) { + existingDeployment.Spec.Template.Spec.Containers[0].Command = desiredDeployment.Spec.Template.Spec.Containers[0].Command + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Env, + desiredDeployment.Spec.Template.Spec.Containers[0].Env) { + existingDeployment.Spec.Template.Spec.Containers[0].Env = desiredDeployment.Spec.Template.Spec.Containers[0].Env + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Volumes, desiredDeployment.Spec.Template.Spec.Volumes) { + existingDeployment.Spec.Template.Spec.Volumes = desiredDeployment.Spec.Template.Spec.Volumes + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Replicas, desiredDeployment.Spec.Replicas) { + existingDeployment.Spec.Replicas = desiredDeployment.Spec.Replicas + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts, desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts) { + existingDeployment.Spec.Template.Spec.Containers[0].VolumeMounts = desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[0].Resources, desiredDeployment.Spec.Template.Spec.Containers[0].Resources) { + existingDeployment.Spec.Template.Spec.Containers[0].Resources = desiredDeployment.Spec.Template.Spec.Containers[0].Resources + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Spec.ServiceAccountName, desiredDeployment.Spec.Template.Spec.ServiceAccountName) { + existingDeployment.Spec.Template.Spec.ServiceAccountName = desiredDeployment.Spec.Template.Spec.ServiceAccountName + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Labels, desiredDeployment.Labels) { + existingDeployment.Labels = desiredDeployment.Labels + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Template.Labels, desiredDeployment.Spec.Template.Labels) { + existingDeployment.Spec.Template.Labels = desiredDeployment.Spec.Template.Labels + deploymentChanged = true + } + + if !reflect.DeepEqual(existingDeployment.Spec.Selector, desiredDeployment.Spec.Selector) { + existingDeployment.Spec.Selector = desiredDeployment.Spec.Selector + deploymentChanged = true + } + + if deploymentChanged { + return r.Client.Update(context.TODO(), existingDeployment) + } + + return nil + +} + +// getDefaultNotificationsConfig returns a map that contains default triggers and template configurations for argocd-notifications-cm +func getDefaultNotificationsConfig() map[string]string { + + notificationsConfig := make(map[string]string) + + // configure default notifications templates + + notificationsConfig["template.app-created"] = `email: + subject: Application {{.app.metadata.name}} has been created. +message: Application {{.app.metadata.name}} has been created. +teams: + title: Application {{.app.metadata.name}} has been created.` + + notificationsConfig["template.app-deleted"] = `email: + subject: Application {{.app.metadata.name}} has been deleted. +message: Application {{.app.metadata.name}} has been deleted. +teams: + title: Application {{.app.metadata.name}} has been deleted.` + + notificationsConfig["template.app-deployed"] = `email: + subject: New version of an application {{.app.metadata.name}} is up and running. +message: | + {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} is now running new version of deployments manifests. +slack: + attachments: | + [{ + "title": "{{ .app.metadata.name}}", + "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#18be52", + "fields": [ + { + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }, + { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + }, + { + "title": "Revision", + "value": "{{.app.status.sync.revision}}", + "short": true + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "title": "{{$c.type}}", + "value": "{{$c.message}}", + "short": true + } + {{end}} + ] + }] + deliveryPolicy: Post + groupingKey: "" + notifyBroadcast: false +teams: + facts: | + [{ + "name": "Sync Status", + "value": "{{.app.status.sync.status}}" + }, + { + "name": "Repository", + "value": "{{.app.spec.source.repoURL}}" + }, + { + "name": "Revision", + "value": "{{.app.status.sync.revision}}" + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "name": "{{$c.type}}", + "value": "{{$c.message}}" + } + {{end}} + ] + potentialAction: |- + [{ + "@type":"OpenUri", + "name":"Operation Application", + "targets":[{ + "os":"default", + "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}" + }] + }, + { + "@type":"OpenUri", + "name":"Open Repository", + "targets":[{ + "os":"default", + "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + }] + }] + themeColor: '#000080' + title: New version of an application {{.app.metadata.name}} is up and running.` + + notificationsConfig["template.app-health-degraded"] = `email: + subject: Application {{.app.metadata.name}} has degraded. +message: | + {{if eq .serviceType "slack"}}:exclamation:{{end}} Application {{.app.metadata.name}} has degraded. + Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. +slack: + attachments: | + [{ + "title": "{{ .app.metadata.name}}", + "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#f4c030", + "fields": [ + { + "title": "Health Status", + "value": "{{.app.status.health.status}}", + "short": true + }, + { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "title": "{{$c.type}}", + "value": "{{$c.message}}", + "short": true + } + {{end}} + ] + }] + deliveryPolicy: Post + groupingKey: "" + notifyBroadcast: false +teams: + facts: | + [{ + "name": "Health Status", + "value": "{{.app.status.health.status}}" + }, + { + "name": "Repository", + "value": "{{.app.spec.source.repoURL}}" + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "name": "{{$c.type}}", + "value": "{{$c.message}}" + } + {{end}} + ] + potentialAction: | + [{ + "@type":"OpenUri", + "name":"Open Application", + "targets":[{ + "os":"default", + "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}" + }] + }, + { + "@type":"OpenUri", + "name":"Open Repository", + "targets":[{ + "os":"default", + "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + }] + }] + themeColor: '#FF0000' + title: Application {{.app.metadata.name}} has degraded.` + + notificationsConfig["template.app-sync-failed"] = `email: + subject: Failed to sync application {{.app.metadata.name}}. +message: | + {{if eq .serviceType "slack"}}:exclamation:{{end}} The sync operation of application {{.app.metadata.name}} has failed at {{.app.status.operationState.finishedAt}} with the following error: {{.app.status.operationState.message}} + Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . +slack: + attachments: | + [{ + "title": "{{ .app.metadata.name}}", + "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#E96D76", + "fields": [ + { + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }, + { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "title": "{{$c.type}}", + "value": "{{$c.message}}", + "short": true + } + {{end}} + ] + }] + deliveryPolicy: Post + groupingKey: "" + notifyBroadcast: false +teams: + facts: | + [{ + "name": "Sync Status", + "value": "{{.app.status.sync.status}}" + }, + { + "name": "Failed at", + "value": "{{.app.status.operationState.finishedAt}}" + }, + { + "name": "Repository", + "value": "{{.app.spec.source.repoURL}}" + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "name": "{{$c.type}}", + "value": "{{$c.message}}" + } + {{end}} + ] + potentialAction: |- + [{ + "@type":"OpenUri", + "name":"Open Operation", + "targets":[{ + "os":"default", + "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" + }] + }, + { + "@type":"OpenUri", + "name":"Open Repository", + "targets":[{ + "os":"default", + "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + }] + }] + themeColor: '#FF0000' + title: Failed to sync application {{.app.metadata.name}}.` + + notificationsConfig["template.app-sync-running"] = `email: + subject: Start syncing application {{.app.metadata.name}}. +message: | + The sync operation of application {{.app.metadata.name}} has started at {{.app.status.operationState.startedAt}}. + Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . +slack: + attachments: | + [{ + "title": "{{ .app.metadata.name}}", + "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#0DADEA", + "fields": [ + { + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }, + { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "title": "{{$c.type}}", + "value": "{{$c.message}}", + "short": true + } + {{end}} + ] + }] + deliveryPolicy: Post + groupingKey: "" + notifyBroadcast: false +teams: + facts: | + [{ + "name": "Sync Status", + "value": "{{.app.status.sync.status}}" + }, + { + "name": "Started at", + "value": "{{.app.status.operationState.startedAt}}" + }, + { + "name": "Repository", + "value": "{{.app.spec.source.repoURL}}" + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "name": "{{$c.type}}", + "value": "{{$c.message}}" + } + {{end}} + ] + potentialAction: |- + [{ + "@type":"OpenUri", + "name":"Open Operation", + "targets":[{ + "os":"default", + "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" + }] + }, + { + "@type":"OpenUri", + "name":"Open Repository", + "targets":[{ + "os":"default", + "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + }] + }] + title: Start syncing application {{.app.metadata.name}}.` + + notificationsConfig["template.app-sync-status-unknown"] = `email: + subject: Application {{.app.metadata.name}} sync status is 'Unknown' +message: | + {{if eq .serviceType "slack"}}:exclamation:{{end}} Application {{.app.metadata.name}} sync is 'Unknown'. + Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. + {{if ne .serviceType "slack"}} + {{range $c := .app.status.conditions}} + * {{$c.message}} + {{end}} + {{end}} +slack: + attachments: | + [{ + "title": "{{ .app.metadata.name}}", + "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#E96D76", + "fields": [ + { + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }, + { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "title": "{{$c.type}}", + "value": "{{$c.message}}", + "short": true + } + {{end}} + ] + }] + deliveryPolicy: Post + groupingKey: "" + notifyBroadcast: false +teams: + facts: | + [{ + "name": "Sync Status", + "value": "{{.app.status.sync.status}}" + }, + { + "name": "Repository", + "value": "{{.app.spec.source.repoURL}}" + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "name": "{{$c.type}}", + "value": "{{$c.message}}" + } + {{end}} + ] + potentialAction: |- + [{ + "@type":"OpenUri", + "name":"Open Application", + "targets":[{ + "os":"default", + "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}" + }] + }, + { + "@type":"OpenUri", + "name":"Open Repository", + "targets":[{ + "os":"default", + "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + }] + }] + title: Application {{.app.metadata.name}} sync status is 'Unknown'` + + notificationsConfig["template.app-sync-succeeded"] = `email: + subject: Application {{.app.metadata.name}} has been successfully synced. +message: | + {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} has been successfully synced at {{.app.status.operationState.finishedAt}}. + Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . +slack: + attachments: | + [{ + "title": "{{ .app.metadata.name}}", + "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + "color": "#18be52", + "fields": [ + { + "title": "Sync Status", + "value": "{{.app.status.sync.status}}", + "short": true + }, + { + "title": "Repository", + "value": "{{.app.spec.source.repoURL}}", + "short": true + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "title": "{{$c.type}}", + "value": "{{$c.message}}", + "short": true + } + {{end}} + ] + }] + deliveryPolicy: Post + groupingKey: "" + notifyBroadcast: false +teams: + facts: | + [{ + "name": "Sync Status", + "value": "{{.app.status.sync.status}}" + }, + { + "name": "Synced at", + "value": "{{.app.status.operationState.finishedAt}}" + }, + { + "name": "Repository", + "value": "{{.app.spec.source.repoURL}}" + } + {{range $index, $c := .app.status.conditions}} + {{if not $index}},{{end}} + {{if $index}},{{end}} + { + "name": "{{$c.type}}", + "value": "{{$c.message}}" + } + {{end}} + ] + potentialAction: |- + [{ + "@type":"OpenUri", + "name":"Operation Details", + "targets":[{ + "os":"default", + "uri":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" + }] + }, + { + "@type":"OpenUri", + "name":"Open Repository", + "targets":[{ + "os":"default", + "uri":"{{.app.spec.source.repoURL | call .repo.RepoURLToHTTPS}}" + }] + }] + themeColor: '#000080' + title: Application {{.app.metadata.name}} has been successfully synced` + + // configure default notifications triggers + + notificationsConfig["trigger.on-created"] = `- description: Application is created. + oncePer: app.metadata.name + send: + - app-created + when: "true"` + + notificationsConfig["trigger.on-deleted"] = `- description: Application is deleted. + oncePer: app.metadata.name + send: + - app-deleted + when: app.metadata.deletionTimestamp != nil` + + notificationsConfig["trigger.on-deployed"] = `- description: Application is synced and healthy. Triggered once per commit. + oncePer: app.status.operationState.syncResult.revision + send: + - app-deployed + when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status + == 'Healthy'` + + notificationsConfig["trigger.on-health-degraded"] = `- description: Application has degraded + send: + - app-health-degraded + when: app.status.health.status == 'Degraded'` + + notificationsConfig["trigger.on-sync-failed"] = `- description: Application syncing has failed + send: + - app-sync-failed + when: app.status.operationState.phase in ['Error', 'Failed']` + + notificationsConfig["trigger.on-sync-running"] = `- description: Application is being synced + send: + - app-sync-running + when: app.status.operationState.phase in ['Running']` + + notificationsConfig["trigger.on-sync-status-unknown"] = `- description: Application status is 'Unknown' + send: + - app-sync-status-unknown + when: app.status.sync.status == 'Unknown'` + + notificationsConfig["trigger.on-sync-succeeded"] = `- description: Application syncing has succeeded + send: + - app-sync-succeeded + when: app.status.operationState.phase in ['Succeeded']` + + return notificationsConfig +} + +// getArgoCDNotificationsControllerReplicas will return the size value for the argocd-notifications-controller replica count if it +// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or +// replicas value is < 0. +func getArgoCDNotificationsControllerReplicas(cr *argoproj.ArgoCD) *int32 { + if cr.Spec.Notifications.Replicas != nil && *cr.Spec.Notifications.Replicas >= 0 { + return cr.Spec.Notifications.Replicas + } + + return nil +} diff --git a/controllers/argocd/redis_TOBEREMOVED.go b/controllers/argocd/redis_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/redis_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/reposerver_TOBEREMOVED.go b/controllers/argocd/reposerver_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/reposerver_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/secret_TOBEREMOVED.go b/controllers/argocd/secret_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/secret_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd diff --git a/controllers/argocd/server_TOBEREMOVED.go b/controllers/argocd/server_TOBEREMOVED.go new file mode 100644 index 000000000..ab81a56a4 --- /dev/null +++ b/controllers/argocd/server_TOBEREMOVED.go @@ -0,0 +1 @@ +package argocd From 13aff1a4de33d86b5e18976953215605bf659472 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 14:03:52 -0500 Subject: [PATCH 71/94] move repo server code to dedicated tbr file Signed-off-by: Jaideep Rao --- controllers/argocd/TOBEREMOVED.go | 595 ------------------ controllers/argocd/reposerver_TOBEREMOVED.go | 615 +++++++++++++++++++ 2 files changed, 615 insertions(+), 595 deletions(-) create mode 100644 controllers/argocd/reposerver_TOBEREMOVED.go diff --git a/controllers/argocd/TOBEREMOVED.go b/controllers/argocd/TOBEREMOVED.go index f7c628cf5..d789f2337 100644 --- a/controllers/argocd/TOBEREMOVED.go +++ b/controllers/argocd/TOBEREMOVED.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "crypto/rand" - "crypto/sha256" "encoding/base64" "errors" "fmt" @@ -2215,597 +2214,3 @@ func newRouteWithName(name string, cr *argoproj.ArgoCD) *routev1.Route { func newRouteWithSuffix(suffix string, cr *argoproj.ArgoCD) *routev1.Route { return newRouteWithName(fmt.Sprintf("%s-%s", cr.Name, suffix), cr) } - -// reconcileStatusRepo will ensure that the Repo status is updated for the given ArgoCD. -func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoproj.ArgoCD) error { - status := "Unknown" - - deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, deploy.Name, deploy) { - status = "Pending" - - if deploy.Spec.Replicas != nil { - if deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { - status = "Running" - } - } - } - - if cr.Status.Repo != status { - cr.Status.Repo = status - return r.Client.Status().Update(context.TODO(), cr) - } - return nil -} - -// reconcileRepoServerTLSSecret checks whether the argocd-repo-server-tls secret -// has changed since our last reconciliation loop. It does so by comparing the -// checksum of tls.crt and tls.key in the status of the ArgoCD CR against the -// values calculated from the live state in the cluster. -func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoproj.ArgoCD) error { - var tlsSecretObj corev1.Secret - var sha256sum string - - log.Info("reconciling repo-server TLS secret") - - tlsSecretName := types.NamespacedName{Namespace: cr.Namespace, Name: common.ArgoCDRepoServerTLSSecretName} - err := r.Client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) - if err != nil { - if !apierrors.IsNotFound(err) { - return err - } - } else if tlsSecretObj.Type != corev1.SecretTypeTLS { - // We only process secrets of type kubernetes.io/tls - return nil - } else { - // We do the checksum over a concatenated byte stream of cert + key - crt, crtOk := tlsSecretObj.Data[corev1.TLSCertKey] - key, keyOk := tlsSecretObj.Data[corev1.TLSPrivateKeyKey] - if crtOk && keyOk { - var sumBytes []byte - sumBytes = append(sumBytes, crt...) - sumBytes = append(sumBytes, key...) - sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) - } - } - - // The content of the TLS secret has changed since we last looked if the - // calculated checksum doesn't match the one stored in the status. - if cr.Status.RepoTLSChecksum != sha256sum { - // We store the value early to prevent a possible restart loop, for the - // cost of a possibly missed restart when we cannot update the status - // field of the resource. - cr.Status.RepoTLSChecksum = sha256sum - err = r.Client.Status().Update(context.TODO(), cr) - if err != nil { - return err - } - - // Trigger rollout of API server - apiDepl := newDeploymentWithSuffix("server", "server", cr) - err = r.triggerRollout(apiDepl, "repo.tls.cert.changed") - if err != nil { - return err - } - - // Trigger rollout of repository server - repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", cr) - err = r.triggerRollout(repoDepl, "repo.tls.cert.changed") - if err != nil { - return err - } - - // Trigger rollout of application controller - controllerSts := newStatefulSetWithSuffix("application-controller", "application-controller", cr) - err = r.triggerRollout(controllerSts, "repo.tls.cert.changed") - if err != nil { - return err - } - } - - return nil -} - -// reconcileRepoService will ensure that the Service for the Argo CD repo server is present. -func (r *ReconcileArgoCD) reconcileRepoService(cr *argoproj.ArgoCD) error { - svc := newServiceWithSuffix("repo-server", "repo-server", cr) - - if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { - if !cr.Spec.Repo.IsEnabled() { - return r.Client.Delete(context.TODO(), svc) - } - if ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) { - return r.Client.Update(context.TODO(), svc) - } - return nil // Service found, do nothing - } - - if !cr.Spec.Repo.IsEnabled() { - return nil - } - - ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) - - svc.Spec.Selector = map[string]string{ - common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), - } - - svc.Spec.Ports = []corev1.ServicePort{ - { - Name: "server", - Port: common.ArgoCDDefaultRepoServerPort, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, { - Name: "metrics", - Port: common.ArgoCDDefaultRepoMetricsPort, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoMetricsPort), - }, - } - - if err := controllerutil.SetControllerReference(cr, svc, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), svc) -} - -// getArgoRepoResources will return the ResourceRequirements for the Argo CD Repo server container. -func getArgoRepoResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { - resources := corev1.ResourceRequirements{} - - // Allow override of resource requirements from CR - if cr.Spec.Repo.Resources != nil { - resources = *cr.Spec.Repo.Resources - } - - return resources -} - -func isRepoServerTLSVerificationRequested(cr *argoproj.ArgoCD) bool { - return cr.Spec.Repo.VerifyTLS -} - -// getRepoServerContainerImage will return the container image for the Repo server. -// -// There are three possible options for configuring the image, and this is the -// order of preference. -// -// 1. from the Spec, the spec.repo field has an image and version to use for -// generating an image reference. -// 2. from the Environment, this looks for the `ARGOCD_REPOSERVER_IMAGE` field and uses -// that if the spec is not configured. -// 3. the default is configured in common.ArgoCDDefaultRepoServerVersion and -// common.ArgoCDDefaultRepoServerImage. -func getRepoServerContainerImage(cr *argoproj.ArgoCD) string { - defaultImg, defaultTag := false, false - img := cr.Spec.Repo.Image - if img == "" { - img = common.ArgoCDDefaultArgoImage - defaultImg = true - } - - tag := cr.Spec.Repo.Version - if tag == "" { - tag = common.ArgoCDDefaultArgoVersion - defaultTag = true - } - if e := os.Getenv(common.ArgoCDImageEnvName); e != "" && (defaultTag && defaultImg) { - return e - } - return argoutil.CombineImageTag(img, tag) -} - -// getRepoServerAddress will return the Argo CD repo server address. -func getRepoServerAddress(cr *argoproj.ArgoCD) string { - if cr.Spec.Repo.Remote != nil && *cr.Spec.Repo.Remote != "" { - return *cr.Spec.Repo.Remote - } - return fqdnServiceRef("repo-server", common.ArgoCDDefaultRepoServerPort, cr) -} - -// getArgoCDRepoServerReplicas will return the size value for the argocd-repo-server replica count if it -// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or -// replicas value is < 0. -func getArgoCDRepoServerReplicas(cr *argoproj.ArgoCD) *int32 { - if cr.Spec.Repo.Replicas != nil && *cr.Spec.Repo.Replicas >= 0 { - return cr.Spec.Repo.Replicas - } - - return nil -} - -// getArgoRepoCommand will return the command for the ArgoCD Repo component. -func getArgoRepoCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { - cmd := make([]string, 0) - - cmd = append(cmd, "uid_entrypoint.sh") - cmd = append(cmd, "argocd-repo-server") - - if cr.Spec.Redis.IsEnabled() { - cmd = append(cmd, "--redis", getRedisServerAddress(cr)) - } else { - log.Info("Redis is Disabled. Skipping adding Redis configuration to Repo Server.") - } - if useTLSForRedis { - cmd = append(cmd, "--redis-use-tls") - if isRedisTLSVerificationDisabled(cr) { - cmd = append(cmd, "--redis-insecure-skip-tls-verify") - } else { - cmd = append(cmd, "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt") - } - } - - cmd = append(cmd, "--loglevel") - cmd = append(cmd, getLogLevel(cr.Spec.Repo.LogLevel)) - - cmd = append(cmd, "--logformat") - cmd = append(cmd, getLogFormat(cr.Spec.Repo.LogFormat)) - - // *** NOTE *** - // Do Not add any new default command line arguments below this. - extraArgs := cr.Spec.Repo.ExtraRepoCommandArgs - err := isMergable(extraArgs, cmd) - if err != nil { - return cmd - } - - cmd = append(cmd, extraArgs...) - return cmd -} - -// reconcileRepoServerServiceMonitor will ensure that the ServiceMonitor is present for the Repo Server metrics Service. -func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoproj.ArgoCD) error { - sm := newServiceMonitorWithSuffix("repo-server-metrics", cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { - if !cr.Spec.Prometheus.Enabled { - // ServiceMonitor exists but enabled flag has been set to false, delete the ServiceMonitor - return r.Client.Delete(context.TODO(), sm) - } - return nil // ServiceMonitor found, do nothing - } - - if !cr.Spec.Prometheus.Enabled { - return nil // Prometheus not enabled, do nothing. - } - - sm.Spec.Selector = metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), - }, - } - sm.Spec.Endpoints = []monitoringv1.Endpoint{ - { - Port: common.ArgoCDMetrics, - }, - } - - if err := controllerutil.SetControllerReference(cr, sm, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), sm) -} - -// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container -func getArgoCmpServerInitCommand() []string { - cmd := make([]string, 0) - cmd = append(cmd, "cp") - cmd = append(cmd, "-n") - cmd = append(cmd, "/usr/local/bin/argocd") - cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") - return cmd -} - -// reconcileRepoDeployment will ensure the Deployment resource is present for the ArgoCD Repo component. -func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { - deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) - automountToken := false - if cr.Spec.Repo.MountSAToken { - automountToken = cr.Spec.Repo.MountSAToken - } - - deploy.Spec.Template.Spec.AutomountServiceAccountToken = &automountToken - - if cr.Spec.Repo.ServiceAccount != "" { - deploy.Spec.Template.Spec.ServiceAccountName = cr.Spec.Repo.ServiceAccount - } - - // Global proxy env vars go first - repoEnv := cr.Spec.Repo.Env - // Environment specified in the CR take precedence over everything else - repoEnv = argoutil.EnvMerge(repoEnv, proxyEnvVars(), false) - if cr.Spec.Repo.ExecTimeout != nil { - repoEnv = argoutil.EnvMerge(repoEnv, []corev1.EnvVar{{Name: "ARGOCD_EXEC_TIMEOUT", Value: fmt.Sprintf("%ds", *cr.Spec.Repo.ExecTimeout)}}, true) - } - - AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) - - deploy.Spec.Template.Spec.InitContainers = []corev1.Container{{ - Name: "copyutil", - Image: getArgoContainerImage(cr), - Command: getArgoCmpServerInitCommand(), - ImagePullPolicy: corev1.PullAlways, - Resources: getArgoRepoResources(cr), - Env: proxyEnvVars(), - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - RunAsNonRoot: boolPtr(true), - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "var-files", - MountPath: "/var/run/argocd", - }, - }, - }} - - if cr.Spec.Repo.InitContainers != nil { - deploy.Spec.Template.Spec.InitContainers = append(deploy.Spec.Template.Spec.InitContainers, cr.Spec.Repo.InitContainers...) - } - - repoServerVolumeMounts := []corev1.VolumeMount{ - { - Name: "ssh-known-hosts", - MountPath: "/app/config/ssh", - }, - { - Name: "tls-certs", - MountPath: "/app/config/tls", - }, - { - Name: "gpg-keys", - MountPath: "/app/config/gpg/source", - }, - { - Name: "gpg-keyring", - MountPath: "/app/config/gpg/keys", - }, - { - Name: "tmp", - MountPath: "/tmp", - }, - { - Name: "argocd-repo-server-tls", - MountPath: "/app/config/reposerver/tls", - }, - { - Name: common.ArgoCDRedisServerTLSSecretName, - MountPath: "/app/config/reposerver/tls/redis", - }, - { - Name: "plugins", - MountPath: "/home/argocd/cmp-server/plugins", - }, - } - - if cr.Spec.Repo.VolumeMounts != nil { - repoServerVolumeMounts = append(repoServerVolumeMounts, cr.Spec.Repo.VolumeMounts...) - } - - deploy.Spec.Template.Spec.Containers = []corev1.Container{{ - Command: getArgoRepoCommand(cr, useTLSForRedis), - Image: getRepoServerContainerImage(cr), - ImagePullPolicy: corev1.PullAlways, - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, - }, - InitialDelaySeconds: 5, - PeriodSeconds: 10, - }, - Env: repoEnv, - Name: "argocd-repo-server", - Ports: []corev1.ContainerPort{ - { - ContainerPort: common.ArgoCDDefaultRepoServerPort, - Name: "server", - }, { - ContainerPort: common.ArgoCDDefaultRepoMetricsPort, - Name: "metrics", - }, - }, - ReadinessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), - }, - }, - InitialDelaySeconds: 5, - PeriodSeconds: 10, - }, - Resources: getArgoRepoResources(cr), - SecurityContext: &corev1.SecurityContext{ - AllowPrivilegeEscalation: boolPtr(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - RunAsNonRoot: boolPtr(true), - }, - VolumeMounts: repoServerVolumeMounts, - }} - - if cr.Spec.Repo.SidecarContainers != nil { - deploy.Spec.Template.Spec.Containers = append(deploy.Spec.Template.Spec.Containers, cr.Spec.Repo.SidecarContainers...) - } - - repoServerVolumes := []corev1.Volume{ - { - Name: "ssh-known-hosts", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDKnownHostsConfigMapName, - }, - }, - }, - }, - { - Name: "tls-certs", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDTLSCertsConfigMapName, - }, - }, - }, - }, - { - Name: "gpg-keys", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: common.ArgoCDGPGKeysConfigMapName, - }, - }, - }, - }, - { - Name: "gpg-keyring", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "tmp", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "argocd-repo-server-tls", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: common.ArgoCDRepoServerTLSSecretName, - Optional: boolPtr(true), - }, - }, - }, - { - Name: common.ArgoCDRedisServerTLSSecretName, - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: common.ArgoCDRedisServerTLSSecretName, - Optional: boolPtr(true), - }, - }, - }, - { - Name: "var-files", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - { - Name: "plugins", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - } - - if cr.Spec.Repo.Volumes != nil { - repoServerVolumes = append(repoServerVolumes, cr.Spec.Repo.Volumes...) - } - - deploy.Spec.Template.Spec.Volumes = repoServerVolumes - - if replicas := getArgoCDRepoServerReplicas(cr); replicas != nil { - deploy.Spec.Replicas = replicas - } - - existing := newDeploymentWithSuffix("repo-server", "repo-server", cr) - if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { - - if !cr.Spec.Repo.IsEnabled() { - log.Info("Existing ArgoCD Repo Server found but should be disabled. Deleting Repo Server") - // Delete existing deployment for ArgoCD Repo Server, if any .. - return r.Client.Delete(context.TODO(), existing) - } - - changed := false - actualImage := existing.Spec.Template.Spec.Containers[0].Image - desiredImage := getRepoServerContainerImage(cr) - if actualImage != desiredImage { - existing.Spec.Template.Spec.Containers[0].Image = desiredImage - if existing.Spec.Template.ObjectMeta.Labels == nil { - existing.Spec.Template.ObjectMeta.Labels = map[string]string{ - "image.upgraded": time.Now().UTC().Format("01022006-150406-MST"), - } - } - existing.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") - changed = true - } - updateNodePlacement(existing, deploy, &changed) - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Volumes, existing.Spec.Template.Spec.Volumes) { - existing.Spec.Template.Spec.Volumes = deploy.Spec.Template.Spec.Volumes - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].VolumeMounts, - existing.Spec.Template.Spec.Containers[0].VolumeMounts) { - existing.Spec.Template.Spec.Containers[0].VolumeMounts = deploy.Spec.Template.Spec.Containers[0].VolumeMounts - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Env, - existing.Spec.Template.Spec.Containers[0].Env) { - existing.Spec.Template.Spec.Containers[0].Env = deploy.Spec.Template.Spec.Containers[0].Env - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Resources, existing.Spec.Template.Spec.Containers[0].Resources) { - existing.Spec.Template.Spec.Containers[0].Resources = deploy.Spec.Template.Spec.Containers[0].Resources - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Command, existing.Spec.Template.Spec.Containers[0].Command) { - existing.Spec.Template.Spec.Containers[0].Command = deploy.Spec.Template.Spec.Containers[0].Command - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[1:], - existing.Spec.Template.Spec.Containers[1:]) { - existing.Spec.Template.Spec.Containers = append(existing.Spec.Template.Spec.Containers[0:1], - deploy.Spec.Template.Spec.Containers[1:]...) - changed = true - } - if !reflect.DeepEqual(deploy.Spec.Template.Spec.InitContainers, existing.Spec.Template.Spec.InitContainers) { - existing.Spec.Template.Spec.InitContainers = deploy.Spec.Template.Spec.InitContainers - changed = true - } - - if !reflect.DeepEqual(deploy.Spec.Replicas, existing.Spec.Replicas) { - existing.Spec.Replicas = deploy.Spec.Replicas - changed = true - } - - if deploy.Spec.Template.Spec.AutomountServiceAccountToken != existing.Spec.Template.Spec.AutomountServiceAccountToken { - existing.Spec.Template.Spec.AutomountServiceAccountToken = deploy.Spec.Template.Spec.AutomountServiceAccountToken - changed = true - } - - if deploy.Spec.Template.Spec.ServiceAccountName != existing.Spec.Template.Spec.ServiceAccountName { - existing.Spec.Template.Spec.ServiceAccountName = deploy.Spec.Template.Spec.ServiceAccountName - changed = true - } - - if changed { - return r.Client.Update(context.TODO(), existing) - } - return nil // Deployment found with nothing to do, move along... - } - - if !cr.Spec.Repo.IsEnabled() { - log.Info("ArgoCD Repo Server disabled. Skipping starting ArgoCD Repo Server.") - return nil - } - - if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { - return err - } - return r.Client.Create(context.TODO(), deploy) -} diff --git a/controllers/argocd/reposerver_TOBEREMOVED.go b/controllers/argocd/reposerver_TOBEREMOVED.go new file mode 100644 index 000000000..c9b40a3ff --- /dev/null +++ b/controllers/argocd/reposerver_TOBEREMOVED.go @@ -0,0 +1,615 @@ +package argocd + +import ( + "context" + "crypto/sha256" + "fmt" + "os" + "reflect" + "time" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +// reconcileStatusRepo will ensure that the Repo status is updated for the given ArgoCD. +func (r *ReconcileArgoCD) reconcileStatusRepo(cr *argoproj.ArgoCD) error { + status := "Unknown" + + deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, deploy.Name, deploy) { + status = "Pending" + + if deploy.Spec.Replicas != nil { + if deploy.Status.ReadyReplicas == *deploy.Spec.Replicas { + status = "Running" + } + } + } + + if cr.Status.Repo != status { + cr.Status.Repo = status + return r.Client.Status().Update(context.TODO(), cr) + } + return nil +} + +// reconcileRepoServerTLSSecret checks whether the argocd-repo-server-tls secret +// has changed since our last reconciliation loop. It does so by comparing the +// checksum of tls.crt and tls.key in the status of the ArgoCD CR against the +// values calculated from the live state in the cluster. +func (r *ReconcileArgoCD) reconcileRepoServerTLSSecret(cr *argoproj.ArgoCD) error { + var tlsSecretObj corev1.Secret + var sha256sum string + + log.Info("reconciling repo-server TLS secret") + + tlsSecretName := types.NamespacedName{Namespace: cr.Namespace, Name: common.ArgoCDRepoServerTLSSecretName} + err := r.Client.Get(context.TODO(), tlsSecretName, &tlsSecretObj) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } else if tlsSecretObj.Type != corev1.SecretTypeTLS { + // We only process secrets of type kubernetes.io/tls + return nil + } else { + // We do the checksum over a concatenated byte stream of cert + key + crt, crtOk := tlsSecretObj.Data[corev1.TLSCertKey] + key, keyOk := tlsSecretObj.Data[corev1.TLSPrivateKeyKey] + if crtOk && keyOk { + var sumBytes []byte + sumBytes = append(sumBytes, crt...) + sumBytes = append(sumBytes, key...) + sha256sum = fmt.Sprintf("%x", sha256.Sum256(sumBytes)) + } + } + + // The content of the TLS secret has changed since we last looked if the + // calculated checksum doesn't match the one stored in the status. + if cr.Status.RepoTLSChecksum != sha256sum { + // We store the value early to prevent a possible restart loop, for the + // cost of a possibly missed restart when we cannot update the status + // field of the resource. + cr.Status.RepoTLSChecksum = sha256sum + err = r.Client.Status().Update(context.TODO(), cr) + if err != nil { + return err + } + + // Trigger rollout of API server + apiDepl := newDeploymentWithSuffix("server", "server", cr) + err = r.triggerRollout(apiDepl, "repo.tls.cert.changed") + if err != nil { + return err + } + + // Trigger rollout of repository server + repoDepl := newDeploymentWithSuffix("repo-server", "repo-server", cr) + err = r.triggerRollout(repoDepl, "repo.tls.cert.changed") + if err != nil { + return err + } + + // Trigger rollout of application controller + controllerSts := newStatefulSetWithSuffix("application-controller", "application-controller", cr) + err = r.triggerRollout(controllerSts, "repo.tls.cert.changed") + if err != nil { + return err + } + } + + return nil +} + +// reconcileRepoService will ensure that the Service for the Argo CD repo server is present. +func (r *ReconcileArgoCD) reconcileRepoService(cr *argoproj.ArgoCD) error { + svc := newServiceWithSuffix("repo-server", "repo-server", cr) + + if argoutil.IsObjectFound(r.Client, cr.Namespace, svc.Name, svc) { + if !cr.Spec.Repo.IsEnabled() { + return r.Client.Delete(context.TODO(), svc) + } + if ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) { + return r.Client.Update(context.TODO(), svc) + } + return nil // Service found, do nothing + } + + if !cr.Spec.Repo.IsEnabled() { + return nil + } + + ensureAutoTLSAnnotation(svc, common.ArgoCDRepoServerTLSSecretName, cr.Spec.Repo.WantsAutoTLS()) + + svc.Spec.Selector = map[string]string{ + common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), + } + + svc.Spec.Ports = []corev1.ServicePort{ + { + Name: "server", + Port: common.ArgoCDDefaultRepoServerPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, { + Name: "metrics", + Port: common.ArgoCDDefaultRepoMetricsPort, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(common.ArgoCDDefaultRepoMetricsPort), + }, + } + + if err := controllerutil.SetControllerReference(cr, svc, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), svc) +} + +// getArgoRepoResources will return the ResourceRequirements for the Argo CD Repo server container. +func getArgoRepoResources(cr *argoproj.ArgoCD) corev1.ResourceRequirements { + resources := corev1.ResourceRequirements{} + + // Allow override of resource requirements from CR + if cr.Spec.Repo.Resources != nil { + resources = *cr.Spec.Repo.Resources + } + + return resources +} + +func isRepoServerTLSVerificationRequested(cr *argoproj.ArgoCD) bool { + return cr.Spec.Repo.VerifyTLS +} + +// getRepoServerContainerImage will return the container image for the Repo server. +// +// There are three possible options for configuring the image, and this is the +// order of preference. +// +// 1. from the Spec, the spec.repo field has an image and version to use for +// generating an image reference. +// 2. from the Environment, this looks for the `ARGOCD_REPOSERVER_IMAGE` field and uses +// that if the spec is not configured. +// 3. the default is configured in common.ArgoCDDefaultRepoServerVersion and +// common.ArgoCDDefaultRepoServerImage. +func getRepoServerContainerImage(cr *argoproj.ArgoCD) string { + defaultImg, defaultTag := false, false + img := cr.Spec.Repo.Image + if img == "" { + img = common.ArgoCDDefaultArgoImage + defaultImg = true + } + + tag := cr.Spec.Repo.Version + if tag == "" { + tag = common.ArgoCDDefaultArgoVersion + defaultTag = true + } + if e := os.Getenv(common.ArgoCDImageEnvName); e != "" && (defaultTag && defaultImg) { + return e + } + return argoutil.CombineImageTag(img, tag) +} + +// getRepoServerAddress will return the Argo CD repo server address. +func getRepoServerAddress(cr *argoproj.ArgoCD) string { + if cr.Spec.Repo.Remote != nil && *cr.Spec.Repo.Remote != "" { + return *cr.Spec.Repo.Remote + } + return fqdnServiceRef("repo-server", common.ArgoCDDefaultRepoServerPort, cr) +} + +// getArgoCDRepoServerReplicas will return the size value for the argocd-repo-server replica count if it +// has been set in argocd CR. Otherwise, nil is returned if the replicas is not set in the argocd CR or +// replicas value is < 0. +func getArgoCDRepoServerReplicas(cr *argoproj.ArgoCD) *int32 { + if cr.Spec.Repo.Replicas != nil && *cr.Spec.Repo.Replicas >= 0 { + return cr.Spec.Repo.Replicas + } + + return nil +} + +// getArgoRepoCommand will return the command for the ArgoCD Repo component. +func getArgoRepoCommand(cr *argoproj.ArgoCD, useTLSForRedis bool) []string { + cmd := make([]string, 0) + + cmd = append(cmd, "uid_entrypoint.sh") + cmd = append(cmd, "argocd-repo-server") + + if cr.Spec.Redis.IsEnabled() { + cmd = append(cmd, "--redis", getRedisServerAddress(cr)) + } else { + log.Info("Redis is Disabled. Skipping adding Redis configuration to Repo Server.") + } + if useTLSForRedis { + cmd = append(cmd, "--redis-use-tls") + if isRedisTLSVerificationDisabled(cr) { + cmd = append(cmd, "--redis-insecure-skip-tls-verify") + } else { + cmd = append(cmd, "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt") + } + } + + cmd = append(cmd, "--loglevel") + cmd = append(cmd, getLogLevel(cr.Spec.Repo.LogLevel)) + + cmd = append(cmd, "--logformat") + cmd = append(cmd, getLogFormat(cr.Spec.Repo.LogFormat)) + + // *** NOTE *** + // Do Not add any new default command line arguments below this. + extraArgs := cr.Spec.Repo.ExtraRepoCommandArgs + err := isMergable(extraArgs, cmd) + if err != nil { + return cmd + } + + cmd = append(cmd, extraArgs...) + return cmd +} + +// reconcileRepoServerServiceMonitor will ensure that the ServiceMonitor is present for the Repo Server metrics Service. +func (r *ReconcileArgoCD) reconcileRepoServerServiceMonitor(cr *argoproj.ArgoCD) error { + sm := newServiceMonitorWithSuffix("repo-server-metrics", cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, sm.Name, sm) { + if !cr.Spec.Prometheus.Enabled { + // ServiceMonitor exists but enabled flag has been set to false, delete the ServiceMonitor + return r.Client.Delete(context.TODO(), sm) + } + return nil // ServiceMonitor found, do nothing + } + + if !cr.Spec.Prometheus.Enabled { + return nil // Prometheus not enabled, do nothing. + } + + sm.Spec.Selector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.ArgoCDKeyName: nameWithSuffix("repo-server", cr), + }, + } + sm.Spec.Endpoints = []monitoringv1.Endpoint{ + { + Port: common.ArgoCDMetrics, + }, + } + + if err := controllerutil.SetControllerReference(cr, sm, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), sm) +} + +// getArgoCmpServerInitCommand will return the command for the ArgoCD CMP Server init container +func getArgoCmpServerInitCommand() []string { + cmd := make([]string, 0) + cmd = append(cmd, "cp") + cmd = append(cmd, "-n") + cmd = append(cmd, "/usr/local/bin/argocd") + cmd = append(cmd, "/var/run/argocd/argocd-cmp-server") + return cmd +} + +// reconcileRepoDeployment will ensure the Deployment resource is present for the ArgoCD Repo component. +func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argoproj.ArgoCD, useTLSForRedis bool) error { + deploy := newDeploymentWithSuffix("repo-server", "repo-server", cr) + automountToken := false + if cr.Spec.Repo.MountSAToken { + automountToken = cr.Spec.Repo.MountSAToken + } + + deploy.Spec.Template.Spec.AutomountServiceAccountToken = &automountToken + + if cr.Spec.Repo.ServiceAccount != "" { + deploy.Spec.Template.Spec.ServiceAccountName = cr.Spec.Repo.ServiceAccount + } + + // Global proxy env vars go first + repoEnv := cr.Spec.Repo.Env + // Environment specified in the CR take precedence over everything else + repoEnv = argoutil.EnvMerge(repoEnv, proxyEnvVars(), false) + if cr.Spec.Repo.ExecTimeout != nil { + repoEnv = argoutil.EnvMerge(repoEnv, []corev1.EnvVar{{Name: "ARGOCD_EXEC_TIMEOUT", Value: fmt.Sprintf("%ds", *cr.Spec.Repo.ExecTimeout)}}, true) + } + + AddSeccompProfileForOpenShift(r.Client, &deploy.Spec.Template.Spec) + + deploy.Spec.Template.Spec.InitContainers = []corev1.Container{{ + Name: "copyutil", + Image: getArgoContainerImage(cr), + Command: getArgoCmpServerInitCommand(), + ImagePullPolicy: corev1.PullAlways, + Resources: getArgoRepoResources(cr), + Env: proxyEnvVars(), + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "var-files", + MountPath: "/var/run/argocd", + }, + }, + }} + + if cr.Spec.Repo.InitContainers != nil { + deploy.Spec.Template.Spec.InitContainers = append(deploy.Spec.Template.Spec.InitContainers, cr.Spec.Repo.InitContainers...) + } + + repoServerVolumeMounts := []corev1.VolumeMount{ + { + Name: "ssh-known-hosts", + MountPath: "/app/config/ssh", + }, + { + Name: "tls-certs", + MountPath: "/app/config/tls", + }, + { + Name: "gpg-keys", + MountPath: "/app/config/gpg/source", + }, + { + Name: "gpg-keyring", + MountPath: "/app/config/gpg/keys", + }, + { + Name: "tmp", + MountPath: "/tmp", + }, + { + Name: "argocd-repo-server-tls", + MountPath: "/app/config/reposerver/tls", + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + MountPath: "/app/config/reposerver/tls/redis", + }, + { + Name: "plugins", + MountPath: "/home/argocd/cmp-server/plugins", + }, + } + + if cr.Spec.Repo.VolumeMounts != nil { + repoServerVolumeMounts = append(repoServerVolumeMounts, cr.Spec.Repo.VolumeMounts...) + } + + deploy.Spec.Template.Spec.Containers = []corev1.Container{{ + Command: getArgoRepoCommand(cr, useTLSForRedis), + Image: getRepoServerContainerImage(cr), + ImagePullPolicy: corev1.PullAlways, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + Env: repoEnv, + Name: "argocd-repo-server", + Ports: []corev1.ContainerPort{ + { + ContainerPort: common.ArgoCDDefaultRepoServerPort, + Name: "server", + }, { + ContainerPort: common.ArgoCDDefaultRepoMetricsPort, + Name: "metrics", + }, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(common.ArgoCDDefaultRepoServerPort), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + Resources: getArgoRepoResources(cr), + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: boolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: boolPtr(true), + }, + VolumeMounts: repoServerVolumeMounts, + }} + + if cr.Spec.Repo.SidecarContainers != nil { + deploy.Spec.Template.Spec.Containers = append(deploy.Spec.Template.Spec.Containers, cr.Spec.Repo.SidecarContainers...) + } + + repoServerVolumes := []corev1.Volume{ + { + Name: "ssh-known-hosts", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDKnownHostsConfigMapName, + }, + }, + }, + }, + { + Name: "tls-certs", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDTLSCertsConfigMapName, + }, + }, + }, + }, + { + Name: "gpg-keys", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: common.ArgoCDGPGKeysConfigMapName, + }, + }, + }, + }, + { + Name: "gpg-keyring", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "tmp", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "argocd-repo-server-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRepoServerTLSSecretName, + Optional: boolPtr(true), + }, + }, + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: common.ArgoCDRedisServerTLSSecretName, + Optional: boolPtr(true), + }, + }, + }, + { + Name: "var-files", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "plugins", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + } + + if cr.Spec.Repo.Volumes != nil { + repoServerVolumes = append(repoServerVolumes, cr.Spec.Repo.Volumes...) + } + + deploy.Spec.Template.Spec.Volumes = repoServerVolumes + + if replicas := getArgoCDRepoServerReplicas(cr); replicas != nil { + deploy.Spec.Replicas = replicas + } + + existing := newDeploymentWithSuffix("repo-server", "repo-server", cr) + if argoutil.IsObjectFound(r.Client, cr.Namespace, existing.Name, existing) { + + if !cr.Spec.Repo.IsEnabled() { + log.Info("Existing ArgoCD Repo Server found but should be disabled. Deleting Repo Server") + // Delete existing deployment for ArgoCD Repo Server, if any .. + return r.Client.Delete(context.TODO(), existing) + } + + changed := false + actualImage := existing.Spec.Template.Spec.Containers[0].Image + desiredImage := getRepoServerContainerImage(cr) + if actualImage != desiredImage { + existing.Spec.Template.Spec.Containers[0].Image = desiredImage + if existing.Spec.Template.ObjectMeta.Labels == nil { + existing.Spec.Template.ObjectMeta.Labels = map[string]string{ + "image.upgraded": time.Now().UTC().Format("01022006-150406-MST"), + } + } + existing.Spec.Template.ObjectMeta.Labels["image.upgraded"] = time.Now().UTC().Format("01022006-150406-MST") + changed = true + } + updateNodePlacement(existing, deploy, &changed) + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Volumes, existing.Spec.Template.Spec.Volumes) { + existing.Spec.Template.Spec.Volumes = deploy.Spec.Template.Spec.Volumes + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].VolumeMounts, + existing.Spec.Template.Spec.Containers[0].VolumeMounts) { + existing.Spec.Template.Spec.Containers[0].VolumeMounts = deploy.Spec.Template.Spec.Containers[0].VolumeMounts + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Env, + existing.Spec.Template.Spec.Containers[0].Env) { + existing.Spec.Template.Spec.Containers[0].Env = deploy.Spec.Template.Spec.Containers[0].Env + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Resources, existing.Spec.Template.Spec.Containers[0].Resources) { + existing.Spec.Template.Spec.Containers[0].Resources = deploy.Spec.Template.Spec.Containers[0].Resources + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[0].Command, existing.Spec.Template.Spec.Containers[0].Command) { + existing.Spec.Template.Spec.Containers[0].Command = deploy.Spec.Template.Spec.Containers[0].Command + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.Containers[1:], + existing.Spec.Template.Spec.Containers[1:]) { + existing.Spec.Template.Spec.Containers = append(existing.Spec.Template.Spec.Containers[0:1], + deploy.Spec.Template.Spec.Containers[1:]...) + changed = true + } + if !reflect.DeepEqual(deploy.Spec.Template.Spec.InitContainers, existing.Spec.Template.Spec.InitContainers) { + existing.Spec.Template.Spec.InitContainers = deploy.Spec.Template.Spec.InitContainers + changed = true + } + + if !reflect.DeepEqual(deploy.Spec.Replicas, existing.Spec.Replicas) { + existing.Spec.Replicas = deploy.Spec.Replicas + changed = true + } + + if deploy.Spec.Template.Spec.AutomountServiceAccountToken != existing.Spec.Template.Spec.AutomountServiceAccountToken { + existing.Spec.Template.Spec.AutomountServiceAccountToken = deploy.Spec.Template.Spec.AutomountServiceAccountToken + changed = true + } + + if deploy.Spec.Template.Spec.ServiceAccountName != existing.Spec.Template.Spec.ServiceAccountName { + existing.Spec.Template.Spec.ServiceAccountName = deploy.Spec.Template.Spec.ServiceAccountName + changed = true + } + + if changed { + return r.Client.Update(context.TODO(), existing) + } + return nil // Deployment found with nothing to do, move along... + } + + if !cr.Spec.Repo.IsEnabled() { + log.Info("ArgoCD Repo Server disabled. Skipping starting ArgoCD Repo Server.") + return nil + } + + if err := controllerutil.SetControllerReference(cr, deploy, r.Scheme); err != nil { + return err + } + return r.Client.Create(context.TODO(), deploy) +} From 10a3bcdeada7f9004740bb4cbf8ea2e2952be9eb Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 14:49:55 -0500 Subject: [PATCH 72/94] remove log verbosities and trace markers in info msgs Signed-off-by: Jaideep Rao --- coding-standards-and-best-practices.md | 10 ++++---- common/notifications.go | 1 + .../argocd/applicationset/applicationset.go | 8 ++----- .../applicationset/applicationset_test.go | 3 --- .../argocd/applicationset/deployment.go | 8 +++---- controllers/argocd/applicationset/role.go | 8 +++---- .../argocd/applicationset/rolebinding.go | 6 ++--- controllers/argocd/applicationset/service.go | 6 ++--- .../argocd/applicationset/serviceaccount.go | 4 ++-- .../argocd/applicationset/webhookroute.go | 6 ++--- controllers/argocd/argocd_controller.go | 23 +++++++++++-------- controllers/argocd/notifications/configmap.go | 6 ++--- .../argocd/notifications/deployment.go | 8 +++---- .../argocd/notifications/notifications.go | 7 ++---- .../notifications/notifications_test.go | 3 --- controllers/argocd/notifications/role.go | 8 +++---- .../argocd/notifications/rolebinding.go | 9 ++++---- controllers/argocd/notifications/secret.go | 6 ++--- .../argocd/notifications/serviceaccount.go | 4 ++-- 19 files changed, 63 insertions(+), 71 deletions(-) diff --git a/coding-standards-and-best-practices.md b/coding-standards-and-best-practices.md index 6111d4f56..595d13861 100644 --- a/coding-standards-and-best-practices.md +++ b/coding-standards-and-best-practices.md @@ -214,18 +214,18 @@ if rr.Instance.Spec.HA.Enabled { acr.Logger.Error(err, "reconcileManagedRoles: failed to retrieve role", "name", existingRole.Name, "namespace", existingRole.Namespace) ``` -- Use debug level (`Logger.V(1).Info`) when recording non-essential information. i.e, information on events that don't block happy path execution, but can provide hints if troubleshooting is needed e.g: +- Use debug level (`Logger.Debug`) when recording non-essential information. i.e, information on events that don't block happy path execution, but can provide hints if troubleshooting is needed e.g: ``` -acr.Logger.V(1).Info("reconcileManagedRoles: one or more mutations could not be applied") -acr.Logger.V(1).Info("reconcileManagedRoles: skip reconciliation in favor of custom role", "name", customRoleName) +acr.Logger.Debug("reconcileManagedRoles: one or more mutations could not be applied") +acr.Logger.Debug("reconcileManagedRoles: skip reconciliation in favor of custom role", "name", customRoleName) ``` -- Use Info level (`Logger.Info` or `Logger.V(0).Info`) for all other info-level logs. Any new action taken by the controller that is critical to normal functioning. +- Use Info level (`Logger.Info`) for all other info-level logs. Any new action taken by the controller that is critical to normal functioning. - - No need to mention function names when logging at `info` level. eg: ``` -acr.Logger.V(0).Info("role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) +acr.Logger.Info("role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) ``` - Only use log statements to log success/error if the function belongs to a controller package and is invoked by the controller. No need to log statements from utility/helper packages. e.g: diff --git a/common/notifications.go b/common/notifications.go index dade5a663..8d544327b 100644 --- a/common/notifications.go +++ b/common/notifications.go @@ -2,6 +2,7 @@ package common // notifications const ( + NotificationsController = "notifications-controller" NotificationsControllerComponent = "argocd-notifications-controller" NotificationsSecretName = "argocd-notifications-secret" NotificationsConfigMapName = "argocd-notifications-cm" diff --git a/controllers/argocd/applicationset/applicationset.go b/controllers/argocd/applicationset/applicationset.go index f7e3a7a6f..991ae7d7e 100644 --- a/controllers/argocd/applicationset/applicationset.go +++ b/controllers/argocd/applicationset/applicationset.go @@ -1,14 +1,13 @@ package applicationset import ( - "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/openshift" + "github.com/argoproj-labs/argocd-operator/pkg/util" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) @@ -17,7 +16,7 @@ type ApplicationSetReconciler struct { Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD - Logger logr.Logger + Logger *util.Logger } var ( @@ -26,9 +25,6 @@ var ( ) func (asr *ApplicationSetReconciler) Reconcile() error { - - asr.Logger = ctrl.Log.WithName(AppSetControllerComponent).WithValues("instance", asr.Instance.Name, "instance-namespace", asr.Instance.Namespace) - resourceName = argoutil.GenerateUniqueResourceName(asr.Instance.Name, asr.Instance.Namespace, AppSetControllerComponent) resourceLabels = common.DefaultResourceLabels(resourceName, asr.Instance.Name, AppSetControllerComponent) diff --git a/controllers/argocd/applicationset/applicationset_test.go b/controllers/argocd/applicationset/applicationset_test.go index a504e6084..b255d83c1 100644 --- a/controllers/argocd/applicationset/applicationset_test.go +++ b/controllers/argocd/applicationset/applicationset_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -24,7 +23,6 @@ func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bo assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(AppSetControllerComponent) return &ApplicationSetReconciler{ Client: cl, @@ -38,6 +36,5 @@ func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bo }, } }), - Logger: logger, } } diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 073480aec..44cc6572a 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -29,7 +29,7 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { desiredDeployment, err := workloads.RequestDeployment(deploymentRequest) if err != nil { asr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - asr.Logger.V(1).Info("reconcileDeployment: one or more mutations could not be applied") + asr.Logger.Debug("reconcileDeployment: one or more mutations could not be applied") return err } @@ -60,7 +60,7 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { asr.Logger.Error(err, "reconcileDeployment: failed to create deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err } - asr.Logger.V(0).Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + asr.Logger.Info("deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return nil } deploymentChanged := false @@ -99,7 +99,7 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { } } - asr.Logger.V(0).Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + asr.Logger.Info("deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) return nil } @@ -111,7 +111,7 @@ func (asr *ApplicationSetReconciler) deleteDeployment(name, namespace string) er asr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) + asr.Logger.Info("deployment deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/role.go b/controllers/argocd/applicationset/role.go index c6e8f468f..9d98d1f7d 100644 --- a/controllers/argocd/applicationset/role.go +++ b/controllers/argocd/applicationset/role.go @@ -33,7 +33,7 @@ func (asr *ApplicationSetReconciler) reconcileRole() error { desiredRole, err := permissions.RequestRole(roleRequest) if err != nil { asr.Logger.Error(err, "reconcileRole: failed to request role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) - asr.Logger.V(1).Info("reconcileRole: one or more mutations could not be applied") + asr.Logger.Debug("reconcileRole: one or more mutations could not be applied") return err } @@ -64,7 +64,7 @@ func (asr *ApplicationSetReconciler) reconcileRole() error { asr.Logger.Error(err, "reconcileRole: failed to create role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return err } - asr.Logger.V(0).Info("reconcileRole: role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) + asr.Logger.Info("role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return nil } @@ -75,7 +75,7 @@ func (asr *ApplicationSetReconciler) reconcileRole() error { return err } } - asr.Logger.V(0).Info("reconcileRole: role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) + asr.Logger.Info("role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) return nil } @@ -87,7 +87,7 @@ func (asr *ApplicationSetReconciler) deleteRole(name, namespace string) error { asr.Logger.Error(err, "DeleteRole: failed to delete role", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteRole: role deleted", "name", name, "namespace", namespace) + asr.Logger.Info("role deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/rolebinding.go b/controllers/argocd/applicationset/rolebinding.go index 852e94d42..8bbcf232c 100644 --- a/controllers/argocd/applicationset/rolebinding.go +++ b/controllers/argocd/applicationset/rolebinding.go @@ -74,7 +74,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { asr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + asr.Logger.Info("roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return nil } @@ -103,7 +103,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { } } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + asr.Logger.Info("roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) return nil } @@ -116,6 +116,6 @@ func (asr *ApplicationSetReconciler) deleteRoleBinding(name, namespace string) e asr.Logger.Error(err, "DeleteRole: failed to delete roleBinding", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteRoleBinding: roleBinding deleted", "name", name, "namespace", namespace) + asr.Logger.Info("roleBinding deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/service.go b/controllers/argocd/applicationset/service.go index e4bcf55d9..931194088 100644 --- a/controllers/argocd/applicationset/service.go +++ b/controllers/argocd/applicationset/service.go @@ -33,7 +33,7 @@ func (asr *ApplicationSetReconciler) reconcileService() error { desiredService, err := networking.RequestService(serviceRequest) if err != nil { asr.Logger.Error(err, "reconcileService: failed to request service", "name", desiredService.Name, "namespace", desiredService.Namespace) - asr.Logger.V(1).Info("reconcileService: one or more mutations could not be applied") + asr.Logger.Debug("reconcileService: one or more mutations could not be applied") return err } @@ -64,7 +64,7 @@ func (asr *ApplicationSetReconciler) reconcileService() error { asr.Logger.Error(err, "reconcileService: failed to create service", "name", desiredService.Name, "namespace", desiredService.Namespace) return err } - asr.Logger.V(0).Info("reconcileService: service created", "name", desiredService.Name, "namespace", desiredService.Namespace) + asr.Logger.Info("service created", "name", desiredService.Name, "namespace", desiredService.Namespace) return nil } @@ -79,7 +79,7 @@ func (asr *ApplicationSetReconciler) deleteService(name, namespace string) error asr.Logger.Error(err, "DeleteService: failed to delete service", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteService: service deleted", "name", name, "namespace", namespace) + asr.Logger.Info("service deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/serviceaccount.go b/controllers/argocd/applicationset/serviceaccount.go index b91d93e3a..2546e8428 100644 --- a/controllers/argocd/applicationset/serviceaccount.go +++ b/controllers/argocd/applicationset/serviceaccount.go @@ -52,7 +52,7 @@ func (asr *ApplicationSetReconciler) reconcileServiceAccount() error { asr.Logger.Error(err, "reconcileServiceAccount: failed to create serviceAccount", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return err } - asr.Logger.V(0).Info("reconcileServiceAccount: serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) + asr.Logger.Info("serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return nil } @@ -67,6 +67,6 @@ func (nr *ApplicationSetReconciler) deleteServiceAccount(name, namespace string) nr.Logger.Error(err, "DeleteServiceAccount: failed to delete serviceAccount", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteServiceAccount: serviceAccount deleted", "name", name, "namespace", namespace) + nr.Logger.Info("erviceAccount deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/applicationset/webhookroute.go b/controllers/argocd/applicationset/webhookroute.go index 8e41ca612..987864332 100644 --- a/controllers/argocd/applicationset/webhookroute.go +++ b/controllers/argocd/applicationset/webhookroute.go @@ -56,7 +56,7 @@ func (asr *ApplicationSetReconciler) reconcileWebhookRoute() error { asr.Logger.Error(err, "reconcileRoute: failed to create route", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) return err } - asr.Logger.V(0).Info("reconcileRoute: route created", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) + asr.Logger.Info("route created", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) return nil } @@ -86,7 +86,7 @@ func (asr *ApplicationSetReconciler) reconcileWebhookRoute() error { } } - asr.Logger.V(0).Info("reconcileRoute: webhook route updated", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) + asr.Logger.Info("webhook route updated", "name", desiredWebhookRoute.Name, "namespace", desiredWebhookRoute.Namespace) return nil } @@ -99,7 +99,7 @@ func (asr *ApplicationSetReconciler) deleteWebhookRoute(name, namespace string) asr.Logger.Error(err, "DeleteRoute: failed to delete route", "name", name, "namespace", namespace) return err } - asr.Logger.V(0).Info("DeleteRoute: route deleted", "name", name, "namespace", namespace) + asr.Logger.Info("route deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 476555542..6f412272c 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -40,8 +40,8 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/monitoring" "github.com/argoproj-labs/argocd-operator/pkg/openshift" + "github.com/argoproj-labs/argocd-operator/pkg/util" - "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -59,6 +59,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) +const ( + ArgoCDController = "argocd-controller" +) + // blank assignment to verify that ArgoCDReconciler implements reconcile.Reconciler var _ reconcile.Reconciler = &ArgoCDReconciler{} @@ -80,7 +84,7 @@ type ArgoCDReconciler struct { Scheme *runtime.Scheme Instance *argoproj.ArgoCD ClusterScoped bool - Logger logr.Logger + Logger *util.Logger ResourceManagedNamespaces map[string]string AppManagedNamespaces map[string]string @@ -134,8 +138,6 @@ var ActiveInstanceMap = make(map[string]string) // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.9.2/pkg/reconcile func (r *ArgoCDReconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { - argocdControllerLog := ctrl.Log.WithName("argocd-controller") - reconcileStartTS := time.Now() defer func() { ReconcileTime.WithLabelValues(request.Namespace).Observe(time.Since(reconcileStartTS).Seconds()) @@ -180,7 +182,7 @@ func (r *ArgoCDReconciler) Reconcile(ctx context.Context, request ctrl.Request) r.Instance = argocd r.ClusterScoped = IsClusterConfigNs(r.Instance.Namespace) - r.Logger = argocdControllerLog.WithValues("instance", r.Instance.Name, "instance-namespace", r.Instance.Namespace) + r.Logger = util.NewLogger(ArgoCDController, "instance", r.Instance.Name, "instance-namespace", r.Instance.Namespace) // if r.Instance.GetDeletionTimestamp() != nil { @@ -404,7 +406,7 @@ func (r *ArgoCDReconciler) setAppManagedNamespaces() error { allowedSourceNamespaces := make(map[string]string) if !r.ClusterScoped { - r.Logger.V(1).Info("setSourceNamespaces: instance is not cluster scoped, skip processing namespaces for application management") + r.Logger.Debug("setSourceNamespaces: instance is not cluster scoped, skip processing namespaces for application management") return nil } @@ -449,7 +451,7 @@ func (r *ArgoCDReconciler) setAppManagedNamespaces() error { // check if desired namespace is already being managed by a different cluster scoped Argo CD instance. If yes, skip it // If not, add ArgoCDArgoprojKeyManagedByClusterArgoCD to it and add it to allowedSourceNamespaces if val, ok := ns.Labels[common.ArgoCDArgoprojKeyManagedByClusterArgoCD]; ok && val != r.Instance.Namespace { - r.Logger.V(1).Info("setSourceNamespaces: skipping namespace as it is already managed by a different instance", "namespace", ns.Name, "managing-instance-namespace", val) + r.Logger.Debug("setSourceNamespaces: skipping namespace as it is already managed by a different instance", "namespace", ns.Name, "managing-instance-namespace", val) continue } else { ns.Labels[common.ArgoCDArgoprojKeyManagedByClusterArgoCD] = r.Instance.Namespace @@ -460,7 +462,7 @@ func (r *ArgoCDReconciler) setAppManagedNamespaces() error { r.Logger.Error(err, "setSourceNamespaces: failed to update namespace", "namespace", ns.Name) continue } - r.Logger.V(1).Info("setSourceNamespaces: labeled namespace", "namespace", ns.Name) + r.Logger.Debug("setSourceNamespaces: labeled namespace", "namespace", ns.Name) continue } allowedSourceNamespaces[desiredNs] = "" @@ -481,7 +483,7 @@ func (r *ArgoCDReconciler) setAppManagedNamespaces() error { r.Logger.Error(err, "setSourceNamespaces: failed to update namespace", "namespace", ns.Name) continue } - r.Logger.V(1).Info("setSourceNamespaces: unlabeled namespace", "namespace", ns.Name) + r.Logger.Debug("setSourceNamespaces: unlabeled namespace", "namespace", ns.Name) continue } } @@ -592,6 +594,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, + Logger: util.NewLogger(common.NotificationsController, "instance", r.Instance.Name, "instance-namespace", r.Instance.Namespace), } appController := &appcontroller.AppControllerReconciler{ @@ -607,6 +610,8 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, + // TO DO: update this later + Logger: util.NewLogger(applicationset.AppSetControllerComponent, "instance", r.Instance.Name, "instance-namespace", r.Instance.Namespace), } ssoController := &sso.SSOReconciler{ diff --git a/controllers/argocd/notifications/configmap.go b/controllers/argocd/notifications/configmap.go index c5b635e2b..5392ade2a 100644 --- a/controllers/argocd/notifications/configmap.go +++ b/controllers/argocd/notifications/configmap.go @@ -28,7 +28,7 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { if err != nil { nr.Logger.Error(err, "reconcileConfigMap: failed to request configMap", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) - nr.Logger.V(1).Info("reconcileConfigMap: one or more mutations could not be applied") + nr.Logger.Debug("reconcileConfigMap: one or more mutations could not be applied") return err } @@ -59,7 +59,7 @@ func (nr *NotificationsReconciler) reconcileConfigMap() error { nr.Logger.Error(err, "reconcileConfigMap: failed to create configMap", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) return err } - nr.Logger.V(0).Info("reconcileConfigMap: configMap created", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) + nr.Logger.Info("configMap created", "name", desiredConfigMap.Name, "namespace", desiredConfigMap.Namespace) return nil } @@ -74,6 +74,6 @@ func (nr *NotificationsReconciler) deleteConfigMap(namespace string) error { nr.Logger.Error(err, "DeleteConfigMap: failed to delete configMap", "name", common.NotificationsConfigMapName, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteConfigMap: configMap deleted", "name", common.NotificationsConfigMapName, "namespace", namespace) + nr.Logger.Info("configMap deleted", "name", common.NotificationsConfigMapName, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index 8d5f75ee6..5d7bf9246 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -29,7 +29,7 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { desiredDeployment, err := workloads.RequestDeployment(deploymentRequest) if err != nil { nr.Logger.Error(err, "reconcileDeployment: failed to request deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) - nr.Logger.V(1).Info("reconcileDeployment: one or more mutations could not be applied") + nr.Logger.Debug("reconcileDeployment: one or more mutations could not be applied") return err } @@ -60,7 +60,7 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { nr.Logger.Error(err, "reconcileDeployment: failed to create deployment", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return err } - nr.Logger.V(0).Info("reconcileDeployment: deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) + nr.Logger.Info("deployment created", "name", desiredDeployment.Name, "namespace", desiredDeployment.Namespace) return nil } deploymentChanged := false @@ -99,7 +99,7 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { } } - nr.Logger.V(0).Info("reconcileDeployment: deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) + nr.Logger.Info("deployment updated", "name", existingDeployment.Name, "namespace", existingDeployment.Namespace) return nil } @@ -111,7 +111,7 @@ func (nr *NotificationsReconciler) deleteDeployment(name, namespace string) erro nr.Logger.Error(err, "DeleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteDeployment: deployment deleted", "name", name, "namespace", namespace) + nr.Logger.Info("deployment deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/notifications.go b/controllers/argocd/notifications/notifications.go index 27b6f0be5..705dce544 100644 --- a/controllers/argocd/notifications/notifications.go +++ b/controllers/argocd/notifications/notifications.go @@ -1,21 +1,20 @@ package notifications import ( - "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + "github.com/argoproj-labs/argocd-operator/pkg/util" ) type NotificationsReconciler struct { Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD - Logger logr.Logger + Logger *util.Logger } var ( @@ -25,8 +24,6 @@ var ( func (nr *NotificationsReconciler) Reconcile() error { - nr.Logger = ctrl.Log.WithName(common.NotificationsControllerComponent).WithValues("instance", nr.Instance.Name, "instance-namespace", nr.Instance.Namespace) - resourceName = argoutil.GenerateUniqueResourceName(nr.Instance.Name, nr.Instance.Namespace, common.NotificationsControllerComponent) resourceLabels = common.DefaultResourceLabels(resourceName, nr.Instance.Name, common.NotificationsControllerComponent) diff --git a/controllers/argocd/notifications/notifications_test.go b/controllers/argocd/notifications/notifications_test.go index c20331b2d..60fd740cb 100644 --- a/controllers/argocd/notifications/notifications_test.go +++ b/controllers/argocd/notifications/notifications_test.go @@ -6,7 +6,6 @@ import ( "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -21,13 +20,11 @@ func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *Noti assert.NoError(t, argoproj.AddToScheme(s)) cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - logger := ctrl.Log.WithName(common.ArgoCDNotificationsControllerComponent) return &NotificationsReconciler{ Client: cl, Scheme: s, Instance: argocdcommon.MakeTestArgoCD(), - Logger: logger, } } diff --git a/controllers/argocd/notifications/role.go b/controllers/argocd/notifications/role.go index 165f27446..a85af8410 100644 --- a/controllers/argocd/notifications/role.go +++ b/controllers/argocd/notifications/role.go @@ -33,7 +33,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { desiredRole, err := permissions.RequestRole(roleRequest) if err != nil { nr.Logger.Error(err, "reconcileRole: failed to request role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) - nr.Logger.V(1).Info("reconcileRole: one or more mutations could not be applied") + nr.Logger.Debug("reconcileRole: one or more mutations could not be applied") return err } @@ -64,7 +64,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { nr.Logger.Error(err, "reconcileRole: failed to create role", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return err } - nr.Logger.V(0).Info("reconcileRole: role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) + nr.Logger.Info("role created", "name", desiredRole.Name, "namespace", desiredRole.Namespace) return nil } @@ -75,7 +75,7 @@ func (nr *NotificationsReconciler) reconcileRole() error { return err } } - nr.Logger.V(0).Info("reconcileRole: role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) + nr.Logger.Info("role updated", "name", existingRole.Name, "namespace", existingRole.Namespace) return nil } @@ -87,7 +87,7 @@ func (nr *NotificationsReconciler) deleteRole(name, namespace string) error { nr.Logger.Error(err, "DeleteRole: failed to delete role", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteRole: role deleted", "name", name, "namespace", namespace) + nr.Logger.Info("role deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/rolebinding.go b/controllers/argocd/notifications/rolebinding.go index ff7c05d9b..09610f917 100644 --- a/controllers/argocd/notifications/rolebinding.go +++ b/controllers/argocd/notifications/rolebinding.go @@ -7,7 +7,6 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/permissions" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -61,7 +60,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { existingRoleBinding, err := permissions.GetRoleBinding(desiredRoleBinding.Name, desiredRoleBinding.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { + if !apierrors.IsNotFound(err) { nr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } @@ -74,7 +73,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { nr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + nr.Logger.Info("roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return nil } @@ -103,7 +102,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { } } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + nr.Logger.Info("roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) return nil } @@ -116,6 +115,6 @@ func (nr *NotificationsReconciler) deleteRoleBinding(name, namespace string) err nr.Logger.Error(err, "DeleteRole: failed to delete roleBinding", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteRoleBinding: roleBinding deleted", "name", name, "namespace", namespace) + nr.Logger.Info("roleBinding deleted", "name", name, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/secret.go b/controllers/argocd/notifications/secret.go index 6b84f6ac0..1f71cbdd8 100644 --- a/controllers/argocd/notifications/secret.go +++ b/controllers/argocd/notifications/secret.go @@ -30,7 +30,7 @@ func (nr *NotificationsReconciler) reconcileSecret() error { desiredSecret, err := workloads.RequestSecret(secretRequest) if err != nil { nr.Logger.Error(err, "reconcileSecret: failed to request secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) - nr.Logger.V(1).Info("reconcileSecret: one or more mutations could not be applied") + nr.Logger.Debug("reconcileSecret: one or more mutations could not be applied") return err } @@ -61,7 +61,7 @@ func (nr *NotificationsReconciler) reconcileSecret() error { nr.Logger.Error(err, "reconcileSecret: failed to create secret", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) return err } - nr.Logger.V(0).Info("reconcileSecret: secret created", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) + nr.Logger.Info("secret created", "name", desiredSecret.Name, "namespace", desiredSecret.Namespace) return nil } @@ -76,6 +76,6 @@ func (nr *NotificationsReconciler) deleteSecret(namespace string) error { nr.Logger.Error(err, "DeleteSecret: failed to delete secret", "name", common.NotificationsSecretName, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteSecret: secret deleted", "name", common.NotificationsSecretName, "namespace", namespace) + nr.Logger.Info("secret deleted", "name", common.NotificationsSecretName, "namespace", namespace) return nil } diff --git a/controllers/argocd/notifications/serviceaccount.go b/controllers/argocd/notifications/serviceaccount.go index 2c9858b4c..addace8e5 100644 --- a/controllers/argocd/notifications/serviceaccount.go +++ b/controllers/argocd/notifications/serviceaccount.go @@ -52,7 +52,7 @@ func (nr *NotificationsReconciler) reconcileServiceAccount() error { nr.Logger.Error(err, "reconcileServiceAccount: failed to create serviceAccount", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return err } - nr.Logger.V(0).Info("reconcileServiceAccount: serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) + nr.Logger.Info("serviceAccount created", "name", desiredServiceAccount.Name, "namespace", desiredServiceAccount.Namespace) return nil } @@ -67,6 +67,6 @@ func (nr *NotificationsReconciler) deleteServiceAccount(name, namespace string) nr.Logger.Error(err, "DeleteServiceAccount: failed to delete serviceAccount", "name", name, "namespace", namespace) return err } - nr.Logger.V(0).Info("DeleteServiceAccount: serviceAccount deleted", "name", name, "namespace", namespace) + nr.Logger.Info("serviceAccount deleted", "name", name, "namespace", namespace) return nil } From 4cc285de9bf286886dbb95dbca7a34999d631ed0 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 15:23:15 -0500 Subject: [PATCH 73/94] start adding unit tests Signed-off-by: Jaideep Rao --- controllers/argocd/redis/helper.go | 2 +- controllers/argocd/redis/redis.go | 4 +- .../argocd/reposerver/servicemonitor.go | 3 +- .../argocd/reposerver/servicemonitor_test.go | 89 ++++++++++--------- 4 files changed, 54 insertions(+), 44 deletions(-) diff --git a/controllers/argocd/redis/helper.go b/controllers/argocd/redis/helper.go index ba3aff5c2..b9e6602da 100644 --- a/controllers/argocd/redis/helper.go +++ b/controllers/argocd/redis/helper.go @@ -15,7 +15,7 @@ func (rr *RedisReconciler) UseTLS() bool { tlsSecret, err := workloads.GetSecret(common.ArgoCDRedisServerTLSSecretName, rr.Instance.Namespace, rr.Client) if err != nil { if apierrors.IsNotFound(err) { - rr.Logger.V(1).Info("skipping TLS enforcement") + rr.Logger.Debug("skipping TLS enforcement") return false } rr.Logger.Error(err, "UseTLS: failed to retrieve tls secret", "name", common.ArgoCDRedisServerTLSSecretName, "namespace", rr.Instance.Namespace) diff --git a/controllers/argocd/redis/redis.go b/controllers/argocd/redis/redis.go index 7a5b4e58e..41e7dd624 100644 --- a/controllers/argocd/redis/redis.go +++ b/controllers/argocd/redis/redis.go @@ -1,18 +1,18 @@ package redis import ( - "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/pkg/util" ) type RedisReconciler struct { Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD - Logger logr.Logger + Logger *util.Logger } func (rr *RedisReconciler) Reconcile() error { diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index bd1043fa2..f55869d23 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -16,7 +16,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { // return if prometheus API is not present on cluster if !monitoring.IsPrometheusAPIAvailable() { - rsr.Logger.V(1).Info("prometheus API unavailable, skip reconciling service monitor") + rsr.Logger.Debug("prometheus API unavailable, skip reconciling service monitor") return nil } @@ -66,6 +66,7 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { func (rsr *RepoServerReconciler) deleteServiceMonitor(name, namespace string) error { // return if prometheus API is not present on cluster if !monitoring.IsPrometheusAPIAvailable() { + rsr.Logger.Debug("prometheus API unavailable, skip deleting service monitor") return nil } diff --git a/controllers/argocd/reposerver/servicemonitor_test.go b/controllers/argocd/reposerver/servicemonitor_test.go index fd47ceef5..ce59474b2 100644 --- a/controllers/argocd/reposerver/servicemonitor_test.go +++ b/controllers/argocd/reposerver/servicemonitor_test.go @@ -1,16 +1,11 @@ package reposerver -// import ( -// "context" -// "testing" +import ( + "testing" -// "github.com/argoproj-labs/argocd-operator/common" -// "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" -// "github.com/argoproj-labs/argocd-operator/pkg/argoutil" -// monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" -// "github.com/stretchr/testify/assert" -// "k8s.io/apimachinery/pkg/types" -// ) + "github.com/argoproj-labs/argocd-operator/tests/test" + "github.com/stretchr/testify/assert" +) // func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { // ns := argocdcommon.MakeTestNamespace() @@ -52,33 +47,47 @@ package reposerver // } // } -// func TestRepoServerReconciler_DeleteServiceMonitor(t *testing.T) { -// ns := argocdcommon.MakeTestNamespace() -// sa := argocdcommon.MakeTestServiceAccount() -// resourceName = argocdcommon.TestArgoCDName -// tests := []struct { -// name string -// setupClient func() *RepoServerReconciler -// wantErr bool -// }{ -// { -// name: "successful delete", -// setupClient: func() *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, ns, sa) -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// rsr := tt.setupClient() -// if err := rsr.deleteServiceMonitor(resourceName, ns.Name); (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } -// }) -// } -// } +func TestDeleteServiceMonitor(t *testing.T) { + tests := []struct { + name string + namespace string + reconciler *RepoServerReconciler + prometheusExist bool + svcMonitorExist bool + expectedError bool + }{ + { + name: "Prometheus API absent", + namespace: test.TestNamespace, + prometheusExist: false, + svcMonitorExist: true, + expectedError: false, + }, + { + name: "Prometheus API present, ServiceMonitor exists", + namespace: test.TestNamespace, + prometheusExist: true, + svcMonitorExist: true, + expectedError: false, + }, + { + name: "Prometheus API present, ServiceMonitor not found", + namespace: test.TestNamespace, + prometheusExist: true, + svcMonitorExist: false, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := rsr.deleteServiceMonitor("test-svc-monitor", tt.namespace) + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + }) + } +} From 047cfc3739f8396ad49dddbe5f8b5933b85b2e93 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 15:27:23 -0500 Subject: [PATCH 74/94] move test reconciler client and scheme to global test pkg Signed-off-by: Jaideep Rao --- controllers/argocd/TOBEREMOVED_test.go | 42 +++++++++++++++++++ controllers/argocd/testing.go | 56 -------------------------- tests/test/testing.go | 29 +++++++++++++ 3 files changed, 71 insertions(+), 56 deletions(-) diff --git a/controllers/argocd/TOBEREMOVED_test.go b/controllers/argocd/TOBEREMOVED_test.go index 0dc7a3c62..d512d79e5 100644 --- a/controllers/argocd/TOBEREMOVED_test.go +++ b/controllers/argocd/TOBEREMOVED_test.go @@ -15,7 +15,9 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" logf "sigs.k8s.io/controller-runtime/pkg/log" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" @@ -1200,3 +1202,43 @@ func TestArgoCDApplicationSetEnv(t *testing.T) { assert.Equal(t, defaultEnv, deployment.Spec.Template.Spec.Containers[0].Env) } + +type SchemeOpt func(*runtime.Scheme) error + +func makeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client.Object, runtimeObj []runtime.Object) client.Client { + client := fake.NewClientBuilder().WithScheme(sch) + if len(resObjs) > 0 { + client = client.WithObjects(resObjs...) + } + if len(subresObjs) > 0 { + client = client.WithStatusSubresource(subresObjs...) + } + if len(runtimeObj) > 0 { + client = client.WithRuntimeObjects(runtimeObj...) + } + return client.Build() +} + +func makeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { + s := scheme.Scheme + for _, opt := range sOpts { + _ = opt(s) + } + + return s +} + +type namespaceOpt func(*corev1.Namespace) + +func makeTestNs(opts ...namespaceOpt) *corev1.Namespace { + a := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-ns", + Labels: make(map[string]string), + }, + } + for _, o := range opts { + o(a) + } + return a +} diff --git a/controllers/argocd/testing.go b/controllers/argocd/testing.go index b0aada082..3d38aa31b 100644 --- a/controllers/argocd/testing.go +++ b/controllers/argocd/testing.go @@ -26,9 +26,7 @@ import ( resourcev1 "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" @@ -46,23 +44,6 @@ func ZapLogger(development bool) logr.Logger { return zap.New(zap.UseDevMode(development)) } -type namespaceOpt func(*corev1.Namespace) - -func makeTestNs(opts ...namespaceOpt) *corev1.Namespace { - a := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-ns", - Labels: make(map[string]string), - }, - } - for _, o := range opts { - o(a) - } - return a -} - -type SchemeOpt func(*runtime.Scheme) error - func makeNewTestReconciler(client client.Client, sch *runtime.Scheme) *ArgoCDReconciler { return &ArgoCDReconciler{ Client: client, @@ -70,29 +51,6 @@ func makeNewTestReconciler(client client.Client, sch *runtime.Scheme) *ArgoCDRec } } -func makeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client.Object, runtimeObj []runtime.Object) client.Client { - client := fake.NewClientBuilder().WithScheme(sch) - if len(resObjs) > 0 { - client = client.WithObjects(resObjs...) - } - if len(subresObjs) > 0 { - client = client.WithStatusSubresource(subresObjs...) - } - if len(runtimeObj) > 0 { - client = client.WithRuntimeObjects(runtimeObj...) - } - return client.Build() -} - -func makeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { - s := scheme.Scheme - for _, opt := range sOpts { - _ = opt(s) - } - - return s -} - type argoCDOpt func(*argoproj.ArgoCD) func makeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { @@ -278,17 +236,3 @@ func makeTestDexResources() *corev1.ResourceRequirements { }, } } - -// func createNs(r *ArgoCDReconciler, n string, managedBy string) error { -// ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: n}} -// if managedBy != "" { -// ns.Labels = map[string]string{common.ArgoCDArgoprojKeyManagedBy: managedBy} -// } - -// if r.ResourceManagedNamespaces == nil { -// r.ResourceManagedNamespaces = make(map[string]string) -// } -// r.ResourceManagedNamespaces[ns.Name] = "" - -// return r.Client.Create(context.TODO(), ns) -// } diff --git a/tests/test/testing.go b/tests/test/testing.go index 261b4e5fa..46a1bbb4c 100644 --- a/tests/test/testing.go +++ b/tests/test/testing.go @@ -9,10 +9,14 @@ import ( corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" ) const ( @@ -38,6 +42,31 @@ var ( } ) +func MakeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client.Object, runtimeObj []runtime.Object) client.Client { + client := fake.NewClientBuilder().WithScheme(sch) + if len(resObjs) > 0 { + client = client.WithObjects(resObjs...) + } + if len(subresObjs) > 0 { + client = client.WithStatusSubresource(subresObjs...) + } + if len(runtimeObj) > 0 { + client = client.WithRuntimeObjects(runtimeObj...) + } + return client.Build() +} + +type SchemeOpt func(*runtime.Scheme) error + +func MakeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { + s := scheme.Scheme + for _, opt := range sOpts { + _ = opt(s) + } + + return s +} + func TestMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { return errors.New("test-mutation-error") } From 33a2660f66a769caadc777e48173e05e85b1a01a Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 15:36:02 -0500 Subject: [PATCH 75/94] rename argocd test reconciler Signed-off-by: Jaideep Rao --- controllers/argocd/TOBEREMOVED_test.go | 13 ++++++++++ controllers/argocd/argocd_controller_test.go | 11 +++++++-- controllers/argocd/testing.go | 26 ++------------------ 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/controllers/argocd/TOBEREMOVED_test.go b/controllers/argocd/TOBEREMOVED_test.go index d512d79e5..57053452f 100644 --- a/controllers/argocd/TOBEREMOVED_test.go +++ b/controllers/argocd/TOBEREMOVED_test.go @@ -1242,3 +1242,16 @@ func makeTestNs(opts ...namespaceOpt) *corev1.Namespace { } return a } + +func makeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { + a := &argoproj.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: testArgoCDName, + Namespace: testNamespace, + }, + } + for _, o := range opts { + o(a) + } + return a +} diff --git a/controllers/argocd/argocd_controller_test.go b/controllers/argocd/argocd_controller_test.go index 39efcfb7d..9ddf9fbbf 100644 --- a/controllers/argocd/argocd_controller_test.go +++ b/controllers/argocd/argocd_controller_test.go @@ -42,6 +42,13 @@ import ( var _ reconcile.Reconciler = &ArgoCDReconciler{} +func makeTestArgoCDReconciler(client client.Client, sch *runtime.Scheme) *ArgoCDReconciler { + return &ArgoCDReconciler{ + Client: client, + Scheme: sch, + } +} + func addFinalizer(finalizer string) argoCDOpt { return func(a *argoproj.ArgoCD) { a.Finalizers = append(a.Finalizers, finalizer) @@ -427,7 +434,7 @@ func TestSetResourceManagedNamespaces(t *testing.T) { sch := makeTestReconcilerScheme(argoproj.AddToScheme) cl := makeTestReconcilerClient(sch, resources, subresObjs, runtimeObjs) - r := makeNewTestReconciler(cl, sch) + r := makeTestArgoCDReconciler(cl, sch) instanceOne := makeTestArgoCD(func(ac *argoproj.ArgoCD) { ac.Namespace = "instance-1" @@ -492,7 +499,7 @@ func TestSetAppManagedNamespaces(t *testing.T) { sch := makeTestReconcilerScheme(argoproj.AddToScheme) cl := makeTestReconcilerClient(sch, resources, subresObjs, runtimeObjs) - r := makeNewTestReconciler(cl, sch) + r := makeTestArgoCDReconciler(cl, sch) instance := makeTestArgoCD(func(ac *argoproj.ArgoCD) { ac.Namespace = "instance-1" diff --git a/controllers/argocd/testing.go b/controllers/argocd/testing.go index 3d38aa31b..33653a138 100644 --- a/controllers/argocd/testing.go +++ b/controllers/argocd/testing.go @@ -25,8 +25,6 @@ import ( v1 "k8s.io/api/rbac/v1" resourcev1 "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" @@ -34,6 +32,8 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" ) +type argoCDOpt func(*argoproj.ArgoCD) + const ( testNamespace = "argocd" testArgoCDName = "argocd" @@ -44,28 +44,6 @@ func ZapLogger(development bool) logr.Logger { return zap.New(zap.UseDevMode(development)) } -func makeNewTestReconciler(client client.Client, sch *runtime.Scheme) *ArgoCDReconciler { - return &ArgoCDReconciler{ - Client: client, - Scheme: sch, - } -} - -type argoCDOpt func(*argoproj.ArgoCD) - -func makeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { - a := &argoproj.ArgoCD{ - ObjectMeta: metav1.ObjectMeta{ - Name: testArgoCDName, - Namespace: testNamespace, - }, - } - for _, o := range opts { - o(a) - } - return a -} - func makeTestArgoCDForKeycloak() *argoproj.ArgoCD { a := &argoproj.ArgoCD{ ObjectMeta: metav1.ObjectMeta{ From 78b4729361d45883adb24a3316bf4bd869c1485e Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 19:48:07 -0500 Subject: [PATCH 76/94] wip add unit tests for repo-server Signed-off-by: Jaideep Rao --- controllers/argocd/argocdcommon/helper.go | 15 ++ controllers/argocd/reposerver/deployment.go | 3 +- .../argocd/reposerver/deployment_test.go | 146 ++++------ controllers/argocd/reposerver/reposerver.go | 41 ++- .../argocd/reposerver/reposerver_test.go | 71 ++--- controllers/argocd/reposerver/secret.go | 3 +- controllers/argocd/reposerver/secret_test.go | 82 ++++-- controllers/argocd/reposerver/service.go | 5 +- controllers/argocd/reposerver/service_test.go | 251 +++++++++++++----- .../argocd/reposerver/serviceaccount.go | 3 +- .../argocd/reposerver/serviceaccount_test.go | 104 ++++++++ .../argocd/reposerver/servicemonitor.go | 54 ++-- .../argocd/reposerver/servicemonitor_test.go | 237 ++++++++++++----- controllers/argocd/reposerver/status.go | 2 +- go.mod | 1 + go.sum | 1 + tests/test/testing.go | 4 +- 17 files changed, 687 insertions(+), 336 deletions(-) create mode 100644 controllers/argocd/reposerver/serviceaccount_test.go diff --git a/controllers/argocd/argocdcommon/helper.go b/controllers/argocd/argocdcommon/helper.go index 3eaf1d514..bdb112038 100644 --- a/controllers/argocd/argocdcommon/helper.go +++ b/controllers/argocd/argocdcommon/helper.go @@ -7,6 +7,12 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/util" ) +type FieldToCompare struct { + Existing interface{} + Desired interface{} + ExtraAction func() +} + func UpdateIfChanged(existingVal, desiredVal interface{}, extraAction func(), changed *bool) { if util.IsPtr(existingVal) && util.IsPtr(desiredVal) { if !reflect.DeepEqual(existingVal, desiredVal) { @@ -19,6 +25,15 @@ func UpdateIfChanged(existingVal, desiredVal interface{}, extraAction func(), ch } } +// PartialMatch accepts a slice of fields to be compared, along with a bool ptr. It compares all the provided fields and sets the bool to false if a mismatch is detected. It assumes that the bool passed into the fn is set to true by default +func PartialMatch(ftc []FieldToCompare, changed *bool) { + for _, field := range ftc { + if !reflect.DeepEqual(field.Existing, field.Desired) { + *changed = false + } + } +} + // IsMergable returns error if any of the extraArgs is already part of the default command Arguments. func IsMergable(extraArgs []string, cmd []string) error { if len(extraArgs) > 0 { diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 6e10bedb6..6eb8ed970 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -364,8 +364,7 @@ func (rsr *RepoServerReconciler) deleteDeployment(name, namespace string) error if apierrors.IsNotFound(err) { return nil } - rsr.Logger.Error(err, "deleteDeployment: failed to delete deployment", "name", name, "namespace", namespace) - return err + return errors.Wrapf(err, "deleteDeployment: failed to delete deployment %s in namespace %s", name, namespace) } rsr.Logger.Info("deployment deleted", "name", name, "namespace", namespace) return nil diff --git a/controllers/argocd/reposerver/deployment_test.go b/controllers/argocd/reposerver/deployment_test.go index 04e398102..773e854ec 100644 --- a/controllers/argocd/reposerver/deployment_test.go +++ b/controllers/argocd/reposerver/deployment_test.go @@ -1,107 +1,55 @@ package reposerver -// import ( -// "context" -// "testing" +import ( + "testing" -// "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" -// "github.com/stretchr/testify/assert" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/argoproj-labs/argocd-operator/tests/test" + "github.com/stretchr/testify/assert" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) -// appsv1 "k8s.io/api/apps/v1" -// "k8s.io/apimachinery/pkg/types" -// ) +func TestDeleteDeployment(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + deploymentExist bool + expectedError bool + }{ + { + name: "Deployment exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestDeployment(), + ), + deploymentExist: true, + expectedError: false, + }, + { + name: "Deployment does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + deploymentExist: false, + expectedError: false, + }, + } -// func TestRepoServerReconciler_reconcileDeployment(t *testing.T) { -// resourceName = argocdcommon.TestArgoCDName -// resourceLabels = testExpectedLabels -// ns := argocdcommon.MakeTestNamespace() -// rsr := makeTestRepoServerReconciler(t, ns) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { -// tests := []struct { -// name string -// setupClient func(useTLSForRedis bool) *RepoServerReconciler -// wantErr bool -// useTLSForRedis bool -// }{ -// { -// name: "create a deployment", -// setupClient: func(useTLSForRedis bool) *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, ns) -// }, -// wantErr: false, -// useTLSForRedis: false, -// }, -// { -// name: "update a deployment when doesn't use TLS for Redis", -// setupClient: func(useTLSForRedis bool) *RepoServerReconciler { -// existingDeployment := rsr.getDesiredDeployment() -// outdatedDeployment := existingDeployment -// outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" -// return makeTestRepoServerReconciler(t, outdatedDeployment, ns) -// }, -// wantErr: false, -// useTLSForRedis: false, -// }, -// { -// name: "update a deployment when use TLS for Redis", -// setupClient: func(useTLSForRedis bool) *RepoServerReconciler { -// existingDeployment := rsr.getDesiredDeployment() -// outdatedDeployment := existingDeployment -// outdatedDeployment.Spec.Template.Spec.ServiceAccountName = "new-service-account" -// return makeTestRepoServerReconciler(t, outdatedDeployment, ns) -// }, -// wantErr: false, -// useTLSForRedis: true, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// asr := tt.setupClient(tt.useTLSForRedis) -// err := asr.reconcileDeployment() -// if (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } + err := tt.reconciler.deleteDeployment(test.TestName, test.TestNamespace) -// updatedDeployment := &appsv1.Deployment{} -// err = asr.Client.Get(context.TODO(), types.NamespacedName{Name: resourceName, Namespace: argocdcommon.TestNamespace}, updatedDeployment) -// if err != nil { -// t.Fatalf("Could not get updated Deployment: %v", err) -// } -// assert.Equal(t, testServiceAccount, updatedDeployment.Spec.Template.Spec.ServiceAccountName) -// }) -// } -// } + if tt.deploymentExist { + _, err := workloads.GetDeployment(test.TestName, test.TestNamespace, tt.reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + } -// func TestRepoServerReconciler_DeleteDeployment(t *testing.T) { -// ns := argocdcommon.MakeTestNamespace() -// resourceName = argocdcommon.TestArgoCDName -// tests := []struct { -// name string -// setupClient func() *RepoServerReconciler -// wantErr bool -// }{ -// { -// name: "successful delete", -// setupClient: func() *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, ns) -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// rsr := tt.setupClient() -// if err := rsr.deleteDeployment(resourceName, ns.Name); (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } -// }) -// } -// } + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + }) + } +} diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index a29f4927b..3b28669cc 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -28,10 +28,7 @@ var ( ) func (rsr *RepoServerReconciler) Reconcile() error { - rsr.Logger = util.NewLogger(common.RepoServerController, "instance", rsr.Instance.Name, "instance-namespace", rsr.Instance.Namespace) - component = common.RepoServerComponent - resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerSuffix) - resourceMetricsName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetricsSuffix) + rsr.varSetter() if err := rsr.reconcileServiceAccount(); err != nil { rsr.Logger.Error(err, "failed to reconcile serviceaccount") @@ -65,6 +62,11 @@ func (rsr *RepoServerReconciler) Reconcile() error { return err } + if err := rsr.reconcileStatus(); err != nil { + rsr.Logger.Error(err, "failed to reconcile status") + return err + } + return nil } @@ -73,23 +75,38 @@ func (rsr *RepoServerReconciler) DeleteResources() error { // delete deployment err := rsr.deleteDeployment(resourceName, rsr.Instance.Namespace) - deletionErr.Append(err) + if err != nil { + rsr.Logger.Error(err, "DeleteResources") + deletionErr.Append(err) + } // delete service monitor err = rsr.deleteServiceMonitor(resourceName, rsr.Instance.Namespace) - deletionErr.Append(err) + if err != nil { + rsr.Logger.Error(err, "DeleteResources") + deletionErr.Append(err) + } // delete service err = rsr.deleteService(resourceName, rsr.Instance.Namespace) - deletionErr.Append(err) + if err != nil { + rsr.Logger.Error(err, "DeleteResources") + deletionErr.Append(err) + } // delete serviceaccount err = rsr.deleteServiceAccount(resourceName, rsr.Instance.Namespace) - deletionErr.Append(err) + if err != nil { + rsr.Logger.Error(err, "DeleteResources") + deletionErr.Append(err) + } // delete TLS secret err = rsr.deleteSecret(common.ArgoCDRepoServerTLSSecretName, rsr.Instance.Namespace) - deletionErr.Append(err) + if err != nil { + rsr.Logger.Error(err, "DeleteResources") + deletionErr.Append(err) + } return deletionErr.ErrOrNil() } @@ -101,3 +118,9 @@ func (rsr *RepoServerReconciler) TriggerRollout(key string) error { } return nil } + +func (rsr *RepoServerReconciler) varSetter() { + component = common.RepoServerComponent + resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerSuffix) + resourceMetricsName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetricsSuffix) +} diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index 159775d3e..81710e9d7 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -1,47 +1,28 @@ package reposerver -// import ( -// "testing" - -// argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" -// "github.com/argoproj-labs/argocd-operator/common" -// "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" -// monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" -// "github.com/stretchr/testify/assert" -// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -// "k8s.io/apimachinery/pkg/runtime" -// "k8s.io/client-go/kubernetes/scheme" -// ctrl "sigs.k8s.io/controller-runtime" -// "sigs.k8s.io/controller-runtime/pkg/client/fake" -// ) - -// var testExpectedLabels = common.DefaultResourceLabels(argocdcommon.TestArgoCDName, argocdcommon.TestNamespace, common.RepoServerControllerComponent) - -// const testServiceAccount = "test-service-account" - -// func makeTestRepoServerReconciler(t *testing.T, objs ...runtime.Object) *RepoServerReconciler { -// s := scheme.Scheme - -// assert.NoError(t, monitoringv1.AddToScheme(s)) -// assert.NoError(t, argoproj.AddToScheme(s)) - -// cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() -// logger := ctrl.Log.WithName(common.RepoServerControllerComponent) - -// return &RepoServerReconciler{ -// Client: cl, -// Scheme: s, -// Instance: argocdcommon.MakeTestArgoCD(func(a *argoproj.ArgoCD) { -// a.Spec.Repo = argoproj.ArgoCDRepoSpec{ -// ServiceAccount: testServiceAccount, -// AutoTLS: common.OpenShift, -// } -// a.ObjectMeta = metav1.ObjectMeta{ -// Name: argocdcommon.TestArgoCDName, -// Namespace: argocdcommon.TestNamespace, -// UID: argocdcommon.TestUID, -// } -// }), -// Logger: logger, -// } -// } +import ( + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func makeTestReposerverReconciler(cr *argoproj.ArgoCD, objs ...runtime.Object) *RepoServerReconciler { + schemeOpt := func(s *runtime.Scheme) { + monitoringv1.AddToScheme(s) + argoproj.AddToScheme(s) + } + sch := test.MakeTestReconcilerScheme(schemeOpt) + + client := test.MakeTestReconcilerClient(sch, []client.Object{}, []client.Object{}, objs) + + return &RepoServerReconciler{ + Client: client, + Scheme: sch, + Instance: cr, + Logger: util.NewLogger(common.RepoServerController), + } +} diff --git a/controllers/argocd/reposerver/secret.go b/controllers/argocd/reposerver/secret.go index 8468c860f..9e835cfe8 100644 --- a/controllers/argocd/reposerver/secret.go +++ b/controllers/argocd/reposerver/secret.go @@ -66,8 +66,7 @@ func (rsr *RepoServerReconciler) deleteSecret(name, namespace string) error { if apierrors.IsNotFound(err) { return nil } - rsr.Logger.Error(err, "deleteSecret: failed to delete secret", "name", name, "namespace", namespace) - return err + return errors.Wrapf(err, "deleteSecret: failed to delete secret %s in namespace %s", name, namespace) } rsr.Logger.Info("secret deleted", "name", name, "namespace", namespace) return nil diff --git a/controllers/argocd/reposerver/secret_test.go b/controllers/argocd/reposerver/secret_test.go index 54459aafd..b24298ccb 100644 --- a/controllers/argocd/reposerver/secret_test.go +++ b/controllers/argocd/reposerver/secret_test.go @@ -1,31 +1,55 @@ package reposerver -// // reconcileTLSSecret() will be tested in e2e tests -// func TestRepoServerReconciler_DeleteSecret(t *testing.T) { -// ns := argocdcommon.MakeTestNamespace() -// tests := []struct { -// name string -// setupClient func() *RepoServerReconciler -// wantErr bool -// }{ -// { -// name: "successful delete", -// setupClient: func() *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, ns) -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// nr := tt.setupClient() -// if err := nr.deleteSecret(ns.Name); (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } -// }) -// } -// } +import ( + "testing" + + "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/argoproj-labs/argocd-operator/tests/test" + "github.com/stretchr/testify/assert" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +func TestDeleteSecret(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + secretExist bool + expectedError bool + }{ + { + name: "Secret exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestSecret(), + ), + secretExist: true, + expectedError: false, + }, + { + name: "Secret does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + secretExist: false, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + err := tt.reconciler.deleteSecret(test.TestName, test.TestNamespace) + + if tt.secretExist { + _, err := workloads.GetSecret(test.TestName, test.TestNamespace, tt.reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + } + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + }) + } +} diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index 49bf3aaf8..1e58c1387 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -76,7 +76,9 @@ func (rsr *RepoServerReconciler) reconcileService() error { existing, desired interface{} extraAction func() }{ + {&existingSvc.Labels, &desiredSvc.Labels, nil}, {&existingSvc.Annotations, &desiredSvc.Annotations, nil}, + {&existingSvc.Spec, &desiredSvc.Spec, nil}, } for _, field := range fieldsToCompare { @@ -100,8 +102,7 @@ func (rsr *RepoServerReconciler) deleteService(name, namespace string) error { if apierrors.IsNotFound(err) { return nil } - rsr.Logger.Error(err, "DeleteService: failed to delete service", "name", name, "namespace", namespace) - return err + return errors.Wrapf(err, "deleteService: failed to delete service %s in namespace %s", name, namespace) } rsr.Logger.Info("service deleted", "name", name, "namespace", namespace) return nil diff --git a/controllers/argocd/reposerver/service_test.go b/controllers/argocd/reposerver/service_test.go index 6163e4186..cc2d2d521 100644 --- a/controllers/argocd/reposerver/service_test.go +++ b/controllers/argocd/reposerver/service_test.go @@ -1,71 +1,188 @@ package reposerver -// func TestRepoServerReconciler_reconcileTLSService(t *testing.T) { -// ns := argocdcommon.MakeTestNamespace() -// sa := argocdcommon.MakeTestServiceAccount() -// resourceName = argocdcommon.TestArgoCDName +import ( + "testing" -// tests := []struct { -// name string -// setupClient func() *RepoServerReconciler -// wantErr bool -// }{ -// { -// name: "create a Service", -// setupClient: func() *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, ns, sa) -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// rsr := tt.setupClient() -// err := rsr.reconcileService() -// if (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } -// currentService := &corev1.Service{} -// err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argocdcommon.TestArgoCDName, Namespace: argocdcommon.TestNamespace}, currentService) -// if err != nil { -// t.Fatalf("Could not get current Service: %v", err) -// } -// assert.Equal(t, GetServiceSpec().Ports, currentService.Spec.Ports) -// }) -// } -// } + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/networking" + "github.com/argoproj-labs/argocd-operator/tests/test" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) -// func TestRepoServerReconciler_DeleteService(t *testing.T) { -// ns := argocdcommon.MakeTestNamespace() -// sa := argocdcommon.MakeTestServiceAccount() -// resourceName = argocdcommon.TestArgoCDName -// tests := []struct { -// name string -// setupClient func() *RepoServerReconciler -// wantErr bool -// }{ -// { -// name: "successful delete", -// setupClient: func() *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, sa, ns) -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// rsr := tt.setupClient() -// if err := rsr.deleteService(resourceName, ns.Name); (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } -// }) -// } -// } +func TestReconcileService(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedError bool + expectedService *corev1.Service + }{ + { + name: "Service does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedError: false, + expectedService: getDesiredSvc(), + }, + { + name: "Service exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestService( + func(svc *corev1.Service) { + svc.Name = "test-argocd-repo-server" + }, + ), + ), + expectedError: false, + expectedService: getDesiredSvc(), + }, + { + name: "Service drift", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestService( + func(svc *corev1.Service) { + svc.Name = "test-argocd-repo-server" + // Modify some fields to simulate drift + svc.Spec.Ports = []corev1.ServicePort{ + { + Name: "server", + Port: 8087, + }, + } + }, + ), + ), + expectedError: false, + expectedService: getDesiredSvc(), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.reconciler.varSetter() + + err := tt.reconciler.reconcileService() + assert.NoError(t, err) + + existing, err := networking.GetService("test-argocd-repo-server", test.TestNamespace, tt.reconciler.Client) + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + if tt.expectedService != nil { + match := true + + // Check for partial match on relevant fields + ftc := []argocdcommon.FieldToCompare{ + { + Existing: existing.Labels, + Desired: tt.expectedService.Labels, + }, + { + Existing: existing.Annotations, + Desired: tt.expectedService.Annotations, + }, + { + Existing: existing.Spec, + Desired: tt.expectedService.Spec, + }, + } + argocdcommon.PartialMatch(ftc, &match) + assert.True(t, match) + } + }) + } +} + +func TestDeleteService(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + serviceExist bool + expectedError bool + }{ + { + name: "Service exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestService(), + ), + serviceExist: true, + expectedError: false, + }, + { + name: "Service does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + serviceExist: false, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + err := tt.reconciler.deleteService(test.TestName, test.TestNamespace) + + if tt.serviceExist { + _, err := networking.GetService(test.TestName, test.TestNamespace, tt.reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + } + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + }) + } +} + +func getDesiredSvc() *corev1.Service { + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-argocd-repo-server", + Namespace: "test-ns", + Labels: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server", + "app.kubernetes.io/part-of": "argocd", + "app.kubernetes.io/instance": "test-argocd", + "app.kubernetes.io/managed-by": "argocd-operator", + "app.kubernetes.io/component": "repo-server", + }, + Annotations: map[string]string{ + "argocds.argoproj.io/name": "test-argocd", + "argocds.argoproj.io/namespace": "test-ns", + }, + }, + Spec: corev1.ServiceSpec{ + Selector: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server", + }, + Ports: []corev1.ServicePort{ + { + Name: "server", + Port: 8081, + Protocol: "TCP", + TargetPort: intstr.FromInt(8081), + }, + { + Name: "metrics", + Port: 8084, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromInt(8084), + }, + }, + }, + } +} diff --git a/controllers/argocd/reposerver/serviceaccount.go b/controllers/argocd/reposerver/serviceaccount.go index 3503d2932..2ade4a4b1 100644 --- a/controllers/argocd/reposerver/serviceaccount.go +++ b/controllers/argocd/reposerver/serviceaccount.go @@ -40,8 +40,7 @@ func (rsr *RepoServerReconciler) deleteServiceAccount(name, namespace string) er if apierrors.IsNotFound(err) { return nil } - rsr.Logger.Error(err, "deleteServiceAccount: failed to delete serviceaccount", "name", name, "namespace", namespace) - return err + return errors.Wrapf(err, "deleteServiceAccount: failed to delete serviceaccount %s in namespace %s", name, namespace) } rsr.Logger.Info("service account deleted", "name", name, "namespace", namespace) return nil diff --git a/controllers/argocd/reposerver/serviceaccount_test.go b/controllers/argocd/reposerver/serviceaccount_test.go new file mode 100644 index 000000000..14e4fe2ac --- /dev/null +++ b/controllers/argocd/reposerver/serviceaccount_test.go @@ -0,0 +1,104 @@ +package reposerver + +import ( + "testing" + + "github.com/argoproj-labs/argocd-operator/pkg/permissions" + "github.com/argoproj-labs/argocd-operator/tests/test" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +func TestReconcileServiceAccount(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedError bool + expectedCreateLogMessage string + }{ + { + name: "ServiceAccount does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedError: false, + expectedCreateLogMessage: "serviceaccount created", + }, + { + name: "ServiceAccount exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestServiceAccount( + func(sa *corev1.ServiceAccount) { + sa.Name = "test-argocd-repo-server" + }, + ), + ), + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.reconciler.varSetter() + err := tt.reconciler.reconcileServiceAccount() + assert.NoError(t, err) + + _, err = permissions.GetServiceAccount("test-argocd-repo-server", test.TestNamespace, tt.reconciler.Client) + + // Validate the error condition + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + }) + } +} + +func TestDeleteServiceAccount(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + serviceAccountExist bool + expectedError bool + }{ + { + name: "ServiceAccount exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestServiceAccount(), + ), + serviceAccountExist: true, + expectedError: false, + }, + { + name: "ServiceAccount does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + serviceAccountExist: false, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + err := tt.reconciler.deleteServiceAccount(test.TestName, test.TestNamespace) + + if tt.serviceAccountExist { + _, err := permissions.GetServiceAccount(test.TestName, test.TestNamespace, tt.reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + } + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + }) + } +} diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index f55869d23..bcaa3d57c 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -2,6 +2,7 @@ package reposerver import ( "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" "github.com/argoproj-labs/argocd-operator/pkg/monitoring" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" @@ -16,11 +17,11 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { // return if prometheus API is not present on cluster if !monitoring.IsPrometheusAPIAvailable() { - rsr.Logger.Debug("prometheus API unavailable, skip reconciling service monitor") + rsr.Logger.Debug("prometheus API unavailable, skip service monitor reconciliation") return nil } - smReq := monitoring.ServiceMonitorRequest{ + req := monitoring.ServiceMonitorRequest{ ObjectMeta: argoutil.GetObjMeta(resourceMetricsName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ @@ -36,37 +37,61 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { }, } - smReq.ObjectMeta.Labels[common.PrometheusReleaseKey] = common.PrometheusOperator + req.ObjectMeta.Labels[common.PrometheusReleaseKey] = common.PrometheusOperator - desiredSM, err := monitoring.RequestServiceMonitor(smReq) + desired, err := monitoring.RequestServiceMonitor(req) if err != nil { - return errors.Wrapf(err, "reconcileServiceMonitor: failed to request service monitor %s", desiredSM.Name) + return errors.Wrapf(err, "reconcileServiceMonitor: failed to request service monitor %s", desired.Name) } - if err = controllerutil.SetControllerReference(rsr.Instance, desiredSM, rsr.Scheme); err != nil { - rsr.Logger.Error(err, "reconcileServiceMonitor: failed to set owner reference for service monitor", "name", desiredSM.Name) + if err = controllerutil.SetControllerReference(rsr.Instance, desired, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileServiceMonitor: failed to set owner reference for service monitor", "name", desired.Name) } - _, err = monitoring.GetServiceMonitor(desiredSM.Name, desiredSM.Namespace, rsr.Client) + existing, err := monitoring.GetServiceMonitor(desired.Name, desired.Namespace, rsr.Client) if err != nil { if !apierrors.IsNotFound(err) { - return errors.Wrapf(err, "reconcileServiceMonitor: failed to retrieve service %s", desiredSM.Name) + return errors.Wrapf(err, "reconcileServiceMonitor: failed to retrieve service monitor %s", desired.Name) } - if err = monitoring.CreateServiceMonitor(desiredSM, rsr.Client); err != nil { - return errors.Wrapf(err, "reconcileServiceMonitor: failed to create service monitor %s", desiredSM.Name) + if err = monitoring.CreateServiceMonitor(desired, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileServiceMonitor: failed to create service monitor %s", desired.Name) } - rsr.Logger.Info("service monitor created", "name", desiredSM.Name, "namespace", desiredSM.Namespace) + rsr.Logger.Info("service monitor created", "name", desired.Name, "namespace", desired.Namespace) return nil } + changed := false + + fieldsToCompare := []struct { + existing, desired interface{} + extraAction func() + }{ + {&existing.Labels, &desired.Labels, nil}, + {&existing.Annotations, &desired.Annotations, nil}, + {&existing.Spec, &desired.Spec, nil}, + } + + for _, field := range fieldsToCompare { + argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &changed) + } + + if !changed { + return nil + } + + if err = monitoring.UpdateServiceMonitor(existing, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileServiceMonitor: failed to update service monitor %s", existing.Name) + } + + rsr.Logger.Info("service monitor updated", "name", existing.Name, "namespace", existing.Namespace) return nil } func (rsr *RepoServerReconciler) deleteServiceMonitor(name, namespace string) error { // return if prometheus API is not present on cluster if !monitoring.IsPrometheusAPIAvailable() { - rsr.Logger.Debug("prometheus API unavailable, skip deleting service monitor") + rsr.Logger.Debug("prometheus API unavailable, skip service monitor deletion") return nil } @@ -74,8 +99,7 @@ func (rsr *RepoServerReconciler) deleteServiceMonitor(name, namespace string) er if apierrors.IsNotFound(err) { return nil } - rsr.Logger.Error(err, "DeleteServiceMonitor: failed to delete servicemonitor", "name", name, "namespace", namespace) - return err + return errors.Wrapf(err, "deleteServiceMonitor: failed to delete service monitor %s in namespace %s", name, namespace) } rsr.Logger.Info("service monitor deleted", "name", name, "namespace", namespace) return nil diff --git a/controllers/argocd/reposerver/servicemonitor_test.go b/controllers/argocd/reposerver/servicemonitor_test.go index ce59474b2..a54c2298c 100644 --- a/controllers/argocd/reposerver/servicemonitor_test.go +++ b/controllers/argocd/reposerver/servicemonitor_test.go @@ -3,85 +3,167 @@ package reposerver import ( "testing" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/monitoring" "github.com/argoproj-labs/argocd-operator/tests/test" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// func TestRepoServerReconciler_reconcileServiceMonitor(t *testing.T) { -// ns := argocdcommon.MakeTestNamespace() -// sa := argocdcommon.MakeTestServiceAccount() - -// resourceName = argocdcommon.TestArgoCDName - -// tests := []struct { -// name string -// setupClient func() *RepoServerReconciler -// wantErr bool -// }{ -// { -// name: "create a ServiceMonitor", -// setupClient: func() *RepoServerReconciler { -// return makeTestRepoServerReconciler(t, ns, sa) -// }, -// wantErr: false, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// rsr := tt.setupClient() -// err := rsr.reconcileServiceMonitor() -// if (err != nil) != tt.wantErr { -// if tt.wantErr { -// t.Errorf("Expected error but did not get one") -// } else { -// t.Errorf("Unexpected error: %v", err) -// } -// } -// currentService := &monitoringv1.ServiceMonitor{} -// err = rsr.Client.Get(context.TODO(), types.NamespacedName{Name: argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetrics), Namespace: argocdcommon.TestNamespace}, currentService) -// if err != nil { -// t.Fatalf("Could not get current Service: %v", err) -// } -// assert.Equal(t, common.ArgoCDMetrics, currentService.Spec.Endpoints[0].Port) -// }) -// } -// } +func TestReconcileServiceMonitor(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + prometheusAPIAvailable bool + expectedError bool + expectedServiceMonitor *monitoringv1.ServiceMonitor + }{ + { + name: "Prometheus API absent", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + prometheusAPIAvailable: false, + expectedError: true, + }, + { + name: "ServiceMonitor does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + prometheusAPIAvailable: true, + expectedError: false, + expectedServiceMonitor: getDesiredSvcMonitor(), + }, + { + name: "ServiceMonitor exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestServiceMonitor( + func(sm *monitoringv1.ServiceMonitor) { + sm.Name = "test-argocd-repo-server-metrics" + }, + ), + ), + prometheusAPIAvailable: true, + expectedError: false, + expectedServiceMonitor: getDesiredSvcMonitor(), + }, + { + name: "ServiceMonitor drift", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestServiceMonitor( + func(sm *monitoringv1.ServiceMonitor) { + sm.Name = "test-argocd-repo-server-metrics" + // Modify some fields to simulate drift + sm.Spec.Endpoints = []monitoringv1.Endpoint{ + { + Port: "diff-port", + }, + } + }, + ), + ), + prometheusAPIAvailable: true, + expectedError: false, + expectedServiceMonitor: getDesiredSvcMonitor(), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.reconciler.varSetter() + + monitoring.SetPrometheusAPIFound(tt.prometheusAPIAvailable) + defer monitoring.SetPrometheusAPIFound(false) + + err := tt.reconciler.reconcileServiceMonitor() + assert.NoError(t, err) + + existing, err := monitoring.GetServiceMonitor("test-argocd-repo-server-metrics", test.TestNamespace, tt.reconciler.Client) + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + if tt.expectedServiceMonitor != nil { + match := true + + ftc := []argocdcommon.FieldToCompare{ + { + Existing: existing.Labels, + Desired: tt.expectedServiceMonitor.Labels, + }, + { + Existing: existing.Annotations, + Desired: tt.expectedServiceMonitor.Annotations, + }, + { + Existing: existing.Spec, + Desired: tt.expectedServiceMonitor.Spec, + }, + } + argocdcommon.PartialMatch(ftc, &match) + assert.True(t, match) + } + }) + } +} func TestDeleteServiceMonitor(t *testing.T) { tests := []struct { - name string - namespace string - reconciler *RepoServerReconciler - prometheusExist bool - svcMonitorExist bool - expectedError bool + name string + reconciler *RepoServerReconciler + prometheusAPIAvailable bool + svcMonitorExist bool + expectedError bool }{ { - name: "Prometheus API absent", - namespace: test.TestNamespace, - prometheusExist: false, - svcMonitorExist: true, - expectedError: false, + name: "Prometheus API absent", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + prometheusAPIAvailable: false, + svcMonitorExist: false, + expectedError: false, }, { - name: "Prometheus API present, ServiceMonitor exists", - namespace: test.TestNamespace, - prometheusExist: true, - svcMonitorExist: true, - expectedError: false, + name: "ServiceMonitor not found", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + prometheusAPIAvailable: true, + svcMonitorExist: false, + expectedError: false, }, { - name: "Prometheus API present, ServiceMonitor not found", - namespace: test.TestNamespace, - prometheusExist: true, - svcMonitorExist: false, - expectedError: false, + name: "ServiceMonitor exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestServiceMonitor(), + ), + prometheusAPIAvailable: true, + svcMonitorExist: true, + expectedError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := rsr.deleteServiceMonitor("test-svc-monitor", tt.namespace) + monitoring.SetPrometheusAPIFound(tt.prometheusAPIAvailable) + defer monitoring.SetPrometheusAPIFound(false) + + err := tt.reconciler.deleteServiceMonitor(test.TestName, test.TestNamespace) + + if tt.svcMonitorExist { + _, err := monitoring.GetServiceMonitor(test.TestName, test.TestNamespace, tt.reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + } if tt.expectedError { assert.Error(t, err, "Expected an error but got none.") @@ -91,3 +173,36 @@ func TestDeleteServiceMonitor(t *testing.T) { }) } } + +func getDesiredSvcMonitor() *monitoringv1.ServiceMonitor { + return &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-argocd-repo-server-metrics", + Namespace: "test-ns", + Labels: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server-metrics", + "app.kubernetes.io/part-of": "argocd", + "app.kubernetes.io/instance": "test-argocd", + "app.kubernetes.io/managed-by": "argocd-operator", + "app.kubernetes.io/component": "repo-server", + "release": "prometheus-operator", + }, + Annotations: map[string]string{ + "argocds.argoproj.io/name": "test-argocd", + "argocds.argoproj.io/namespace": "test-ns", + }, + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server", + }, + }, + Endpoints: []monitoringv1.Endpoint{ + { + Port: "metrics", + }, + }, + }, + } +} diff --git a/controllers/argocd/reposerver/status.go b/controllers/argocd/reposerver/status.go index 5cae2f750..760797a28 100644 --- a/controllers/argocd/reposerver/status.go +++ b/controllers/argocd/reposerver/status.go @@ -14,7 +14,7 @@ func (rsr *RepoServerReconciler) reconcileStatus() error { deploy, err := workloads.GetDeployment(resourceName, rsr.Instance.Namespace, rsr.Client) if err != nil { - return errors.Wrapf(err, "failed to retrieve deployment %s", resourceName) + return errors.Wrapf(err, "reconcileStatus: failed to retrieve deployment %s", resourceName) } status = common.ArgoCDStatusPending diff --git a/go.mod b/go.mod index 1dd89fff6..cb0fb4072 100644 --- a/go.mod +++ b/go.mod @@ -59,6 +59,7 @@ require ( github.com/prometheus/procfs v0.10.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect diff --git a/go.sum b/go.sum index 014c29c9f..e94e3e94b 100644 --- a/go.sum +++ b/go.sum @@ -1787,6 +1787,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/tests/test/testing.go b/tests/test/testing.go index 46a1bbb4c..174ff8360 100644 --- a/tests/test/testing.go +++ b/tests/test/testing.go @@ -56,12 +56,12 @@ func MakeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client. return client.Build() } -type SchemeOpt func(*runtime.Scheme) error +type SchemeOpt func(*runtime.Scheme) func MakeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { s := scheme.Scheme for _, opt := range sOpts { - _ = opt(s) + opt(s) } return s From 45b5300f75dcbc122ff3588c66bbb3a1079cce89 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sat, 27 Jan 2024 21:32:56 -0500 Subject: [PATCH 77/94] update all references to updateifchanged Signed-off-by: Jaideep Rao --- .../argocd/applicationset/deployment.go | 36 +++++----- .../argocd/applicationset/rolebinding.go | 65 ++++++++++--------- .../argocd/applicationset/webhookroute.go | 23 +++---- controllers/argocd/argocdcommon/helper.go | 32 +++++++-- .../argocd/notifications/deployment.go | 35 +++++----- .../argocd/notifications/rolebinding.go | 65 ++++++++++--------- 6 files changed, 131 insertions(+), 125 deletions(-) diff --git a/controllers/argocd/applicationset/deployment.go b/controllers/argocd/applicationset/deployment.go index 073480aec..b27594270 100644 --- a/controllers/argocd/applicationset/deployment.go +++ b/controllers/argocd/applicationset/deployment.go @@ -65,31 +65,27 @@ func (asr *ApplicationSetReconciler) reconcileDeployment() error { } deploymentChanged := false - fieldsToCompare := []struct { - existing, desired interface{} - extraAction func() - }{ - {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, - func() { + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Image, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Image, + ExtraAction: func() { existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, - {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, - {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, - {&existingDeployment.Spec.Template.Spec.NodeSelector, &desiredDeployment.Spec.Template.Spec.NodeSelector, nil}, - {&existingDeployment.Spec.Template.Spec.Tolerations, &desiredDeployment.Spec.Template.Spec.Tolerations, nil}, - {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, - {&existingDeployment.Spec.Template.Labels, &desiredDeployment.Spec.Template.Labels, nil}, - {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, - {&existingDeployment.Spec.Selector, &desiredDeployment.Spec.Selector, nil}, - {&existingDeployment.Labels, &desiredDeployment.Labels, nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Command, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Command, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Env, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Env, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Resources, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Volumes, Desired: &desiredDeployment.Spec.Template.Spec.Volumes, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.NodeSelector, Desired: &desiredDeployment.Spec.Template.Spec.NodeSelector, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Tolerations, Desired: &desiredDeployment.Spec.Template.Spec.Tolerations, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.ServiceAccountName, Desired: &desiredDeployment.Spec.Template.Spec.ServiceAccountName, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Labels, Desired: &desiredDeployment.Spec.Template.Labels, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Replicas, Desired: &desiredDeployment.Spec.Replicas, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Selector, Desired: &desiredDeployment.Spec.Selector, ExtraAction: nil}, + {Existing: &existingDeployment.Labels, Desired: &desiredDeployment.Labels, ExtraAction: nil}, + {Existing: &existingDeployment.Annotations, Desired: &desiredDeployment.Annotations, ExtraAction: nil}, } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deploymentChanged) - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &deploymentChanged) if deploymentChanged { diff --git a/controllers/argocd/applicationset/rolebinding.go b/controllers/argocd/applicationset/rolebinding.go index 852e94d42..97971444e 100644 --- a/controllers/argocd/applicationset/rolebinding.go +++ b/controllers/argocd/applicationset/rolebinding.go @@ -1,13 +1,15 @@ package applicationset import ( + "reflect" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/permissions" + "github.com/pkg/errors" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -45,7 +47,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { }, } - desiredRoleBinding := permissions.RequestRoleBinding(roleBindingRequest) + desiredRb := permissions.RequestRoleBinding(roleBindingRequest) namespace, err := cluster.GetNamespace(asr.Instance.Namespace, asr.Client) if err != nil { @@ -53,58 +55,57 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { return err } if namespace.DeletionTimestamp != nil { - if err := asr.deleteRole(desiredRoleBinding.Name, desiredRoleBinding.Namespace); err != nil { - asr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if err := asr.deleteRole(desiredRb.Name, desiredRb.Namespace); err != nil { + asr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) } return err } - existingRoleBinding, err := permissions.GetRoleBinding(desiredRoleBinding.Name, desiredRoleBinding.Namespace, asr.Client) + existingRb, err := permissions.GetRoleBinding(desiredRb.Name, desiredRb.Namespace, asr.Client) if err != nil { - if !errors.IsNotFound(err) { - asr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if !apierrors.IsNotFound(err) { + asr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) return err } - if err = controllerutil.SetControllerReference(asr.Instance, desiredRoleBinding, asr.Scheme); err != nil { - asr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if err = controllerutil.SetControllerReference(asr.Instance, desiredRb, asr.Scheme); err != nil { + asr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRb.Name, "namespace", desiredRb.Namespace) } - if err = permissions.CreateRoleBinding(desiredRoleBinding, asr.Client); err != nil { - asr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if err = permissions.CreateRoleBinding(desiredRb, asr.Client); err != nil { + asr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) return err } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRb.Name, "namespace", desiredRb.Namespace) return nil } - roleBindingChanged := false - fieldsToCompare := []struct { - existing, desired interface{} - }{ - { - &existingRoleBinding.RoleRef, - &desiredRoleBinding.RoleRef, - }, - { - &existingRoleBinding.Subjects, - &desiredRoleBinding.Subjects, - }, + // if roleRef differs, we must delete the rolebinding as kubernetes does not allow updation of roleRef + if !reflect.DeepEqual(existingRb.RoleRef, desiredRb.RoleRef) { + asr.Logger.Info("detected drift in roleRef for rolebinding", "name", existingRb.Name, "namespace", existingRb.Namespace) + if err := asr.deleteRoleBinding(resourceName, asr.Instance.Namespace); err != nil { + return errors.Wrapf(err, "reconcileRoleBinding: unable to delete obsolete rolebinding %s", existingRb.Name) + } + return nil } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, nil, &roleBindingChanged) + rbChanged := false + + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existingRb.Subjects, Desired: &desiredRb.Subjects, ExtraAction: nil}, } - if roleBindingChanged { - if err = permissions.UpdateRoleBinding(existingRoleBinding, asr.Client); err != nil { - asr.Logger.Error(err, "reconcileRoleBinding: failed to update roleBinding", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) - return err - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &rbChanged) + + if !rbChanged { + return nil } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + if err = permissions.UpdateRoleBinding(existingRb, asr.Client); err != nil { + return errors.Wrapf(err, "reconcileRoleBinding: failed to update role %s", existingRb.Name) + } + asr.Logger.Info("rolebinding updated", "name", existingRb.Name, "namespace", existingRb.Namespace) return nil } diff --git a/controllers/argocd/applicationset/webhookroute.go b/controllers/argocd/applicationset/webhookroute.go index 8e41ca612..e04e83467 100644 --- a/controllers/argocd/applicationset/webhookroute.go +++ b/controllers/argocd/applicationset/webhookroute.go @@ -62,22 +62,17 @@ func (asr *ApplicationSetReconciler) reconcileWebhookRoute() error { webhookRouteChanged := false - fieldsToCompare := []struct { - existing, desired interface{} - extraAction func() - }{ - {&existingRoute.Annotations, &desiredWebhookRoute.Annotations, nil}, - {&existingRoute.Labels, &desiredWebhookRoute.Labels, nil}, - {&existingRoute.Spec.WildcardPolicy, &desiredWebhookRoute.Spec.WildcardPolicy, nil}, - {&existingRoute.Spec.Host, &desiredWebhookRoute.Spec.Host, nil}, - {&existingRoute.Spec.Port, &desiredWebhookRoute.Spec.Port, nil}, - {&existingRoute.Spec.TLS, &desiredWebhookRoute.Spec.TLS, nil}, - {&existingRoute.Spec.To, &desiredWebhookRoute.Spec.To, nil}, + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existingRoute.Annotations, Desired: &desiredWebhookRoute.Annotations, ExtraAction: nil}, + {Existing: &existingRoute.Labels, Desired: &desiredWebhookRoute.Labels, ExtraAction: nil}, + {Existing: &existingRoute.Spec.WildcardPolicy, Desired: &desiredWebhookRoute.Spec.WildcardPolicy, ExtraAction: nil}, + {Existing: &existingRoute.Spec.Host, Desired: &desiredWebhookRoute.Spec.Host, ExtraAction: nil}, + {Existing: &existingRoute.Spec.Port, Desired: &desiredWebhookRoute.Spec.Port, ExtraAction: nil}, + {Existing: &existingRoute.Spec.TLS, Desired: &desiredWebhookRoute.Spec.TLS, ExtraAction: nil}, + {Existing: &existingRoute.Spec.To, Desired: &desiredWebhookRoute.Spec.To, ExtraAction: nil}, } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &webhookRouteChanged) - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &webhookRouteChanged) if webhookRouteChanged { if err = openshift.UpdateRoute(existingRoute, asr.Client); err != nil { diff --git a/controllers/argocd/argocdcommon/helper.go b/controllers/argocd/argocdcommon/helper.go index 3eaf1d514..6a998b3af 100644 --- a/controllers/argocd/argocdcommon/helper.go +++ b/controllers/argocd/argocdcommon/helper.go @@ -7,14 +7,32 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/util" ) -func UpdateIfChanged(existingVal, desiredVal interface{}, extraAction func(), changed *bool) { - if util.IsPtr(existingVal) && util.IsPtr(desiredVal) { - if !reflect.DeepEqual(existingVal, desiredVal) { - reflect.ValueOf(existingVal).Elem().Set(reflect.ValueOf(desiredVal).Elem()) - if extraAction != nil { - extraAction() +type FieldToCompare struct { + Existing interface{} + Desired interface{} + ExtraAction func() +} + +// UpdateIfChanged accepts a slice of fields to be compared, along with a bool ptr. It compares all the provided fields, updating any fields and setting the bool ptr to true if a drift is detected +func UpdateIfChanged(ftc []FieldToCompare, changed *bool) { + for _, field := range ftc { + if util.IsPtr(field.Existing) && util.IsPtr(field.Desired) { + if !reflect.DeepEqual(field.Existing, field.Desired) { + reflect.ValueOf(field.Existing).Elem().Set(reflect.ValueOf(field.Desired).Elem()) + if field.ExtraAction != nil { + field.ExtraAction() + } + *changed = true } - *changed = true + } + } +} + +// PartialMatch accepts a slice of fields to be compared, along with a bool ptr. It compares all the provided fields and sets the bool to false if a drift is detected +func PartialMatch(ftc []FieldToCompare, match *bool) { + for _, field := range ftc { + if !reflect.DeepEqual(field.Existing, field.Desired) { + *match = false } } } diff --git a/controllers/argocd/notifications/deployment.go b/controllers/argocd/notifications/deployment.go index 8d5f75ee6..6e93e42f4 100644 --- a/controllers/argocd/notifications/deployment.go +++ b/controllers/argocd/notifications/deployment.go @@ -65,31 +65,26 @@ func (nr *NotificationsReconciler) reconcileDeployment() error { } deploymentChanged := false - fieldsToCompare := []struct { - existing, desired interface{} - extraAction func() - }{ - {&existingDeployment.Spec.Template.Spec.Containers[0].Image, &desiredDeployment.Spec.Template.Spec.Containers[0].Image, - func() { + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Image, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Image, + ExtraAction: func() { existingDeployment.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, - {&existingDeployment.Spec.Template.Spec.Containers[0].Command, &desiredDeployment.Spec.Template.Spec.Containers[0].Command, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Env, &desiredDeployment.Spec.Template.Spec.Containers[0].Env, nil}, - {&existingDeployment.Spec.Template.Spec.Containers[0].Resources, &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, nil}, - {&existingDeployment.Spec.Template.Spec.Volumes, &desiredDeployment.Spec.Template.Spec.Volumes, nil}, - {&existingDeployment.Spec.Template.Spec.NodeSelector, &desiredDeployment.Spec.Template.Spec.NodeSelector, nil}, - {&existingDeployment.Spec.Template.Spec.Tolerations, &desiredDeployment.Spec.Template.Spec.Tolerations, nil}, - {&existingDeployment.Spec.Template.Spec.ServiceAccountName, &desiredDeployment.Spec.Template.Spec.ServiceAccountName, nil}, - {&existingDeployment.Spec.Template.Labels, &desiredDeployment.Spec.Template.Labels, nil}, - {&existingDeployment.Spec.Replicas, &desiredDeployment.Spec.Replicas, nil}, - {&existingDeployment.Spec.Selector, &desiredDeployment.Spec.Selector, nil}, - {&existingDeployment.Labels, &desiredDeployment.Labels, nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Command, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Command, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Env, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Env, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Containers[0].Resources, Desired: &desiredDeployment.Spec.Template.Spec.Containers[0].Resources, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Volumes, Desired: &desiredDeployment.Spec.Template.Spec.Volumes, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.NodeSelector, Desired: &desiredDeployment.Spec.Template.Spec.NodeSelector, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.Tolerations, Desired: &desiredDeployment.Spec.Template.Spec.Tolerations, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Spec.ServiceAccountName, Desired: &desiredDeployment.Spec.Template.Spec.ServiceAccountName, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Template.Labels, Desired: &desiredDeployment.Spec.Template.Labels, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Replicas, Desired: &desiredDeployment.Spec.Replicas, ExtraAction: nil}, + {Existing: &existingDeployment.Spec.Selector, Desired: &desiredDeployment.Spec.Selector, ExtraAction: nil}, + {Existing: &existingDeployment.Labels, Desired: &desiredDeployment.Labels, ExtraAction: nil}, } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deploymentChanged) - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &deploymentChanged) if deploymentChanged { diff --git a/controllers/argocd/notifications/rolebinding.go b/controllers/argocd/notifications/rolebinding.go index ff7c05d9b..c82903dc0 100644 --- a/controllers/argocd/notifications/rolebinding.go +++ b/controllers/argocd/notifications/rolebinding.go @@ -1,13 +1,15 @@ package notifications import ( + "reflect" + "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/cluster" "github.com/argoproj-labs/argocd-operator/pkg/permissions" + "github.com/pkg/errors" rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -45,7 +47,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { }, } - desiredRoleBinding := permissions.RequestRoleBinding(roleBindingRequest) + desiredRb := permissions.RequestRoleBinding(roleBindingRequest) namespace, err := cluster.GetNamespace(nr.Instance.Namespace, nr.Client) if err != nil { @@ -53,58 +55,57 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { return err } if namespace.DeletionTimestamp != nil { - if err := nr.deleteRole(desiredRoleBinding.Name, desiredRoleBinding.Namespace); err != nil { - nr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if err := nr.deleteRole(desiredRb.Name, desiredRb.Namespace); err != nil { + nr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) } return err } - existingRoleBinding, err := permissions.GetRoleBinding(desiredRoleBinding.Name, desiredRoleBinding.Namespace, nr.Client) + existingRb, err := permissions.GetRoleBinding(desiredRb.Name, desiredRb.Namespace, nr.Client) if err != nil { - if !errors.IsNotFound(err) { - nr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if !apierrors.IsNotFound(err) { + nr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) return err } - if err = controllerutil.SetControllerReference(nr.Instance, desiredRoleBinding, nr.Scheme); err != nil { - nr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if err = controllerutil.SetControllerReference(nr.Instance, desiredRb, nr.Scheme); err != nil { + nr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRb.Name, "namespace", desiredRb.Namespace) } - if err = permissions.CreateRoleBinding(desiredRoleBinding, nr.Client); err != nil { - nr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + if err = permissions.CreateRoleBinding(desiredRb, nr.Client); err != nil { + nr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) return err } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) + nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRb.Name, "namespace", desiredRb.Namespace) return nil } - roleBindingChanged := false - fieldsToCompare := []struct { - existing, desired interface{} - }{ - { - &existingRoleBinding.RoleRef, - &desiredRoleBinding.RoleRef, - }, - { - &existingRoleBinding.Subjects, - &desiredRoleBinding.Subjects, - }, + // if roleRef differs, we must delete the rolebinding as kubernetes does not allow updation of roleRef + if !reflect.DeepEqual(existingRb.RoleRef, desiredRb.RoleRef) { + nr.Logger.Info("detected drift in roleRef for rolebinding", "name", existingRb.Name, "namespace", existingRb.Namespace) + if err := nr.deleteRoleBinding(resourceName, nr.Instance.Namespace); err != nil { + return errors.Wrapf(err, "reconcileRoleBinding: unable to delete obsolete rolebinding %s", existingRb.Name) + } + return nil } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, nil, &roleBindingChanged) + rbChanged := false + + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existingRb.Subjects, Desired: &desiredRb.Subjects, ExtraAction: nil}, } - if roleBindingChanged { - if err = permissions.UpdateRoleBinding(existingRoleBinding, nr.Client); err != nil { - nr.Logger.Error(err, "reconcileRoleBinding: failed to update roleBinding", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) - return err - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &rbChanged) + + if !rbChanged { + return nil } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + if err = permissions.UpdateRoleBinding(existingRb, nr.Client); err != nil { + return errors.Wrapf(err, "reconcileRoleBinding: failed to update role %s", existingRb.Name) + } + nr.Logger.Info("rolebinding updated", "name", existingRb.Name, "namespace", existingRb.Namespace) return nil } From 7531759c761b7df6924569ed315140d76f4d3ee6 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 00:35:13 -0500 Subject: [PATCH 78/94] finish adding unit tests Signed-off-by: Jaideep Rao --- controllers/argocd/reposerver/deployment.go | 94 +++++++++---------- controllers/argocd/reposerver/helper.go | 6 +- controllers/argocd/reposerver/service.go | 45 ++++----- .../argocd/reposerver/serviceaccount.go | 12 +-- .../argocd/reposerver/servicemonitor.go | 15 +-- 5 files changed, 80 insertions(+), 92 deletions(-) diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 6eb8ed970..9c8e7b15f 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -29,81 +29,78 @@ const ( func (rsr *RepoServerReconciler) reconcileDeployment() error { - deployReq := rsr.getDeploymentRequest() + req := rsr.getDeploymentRequest() - desiredDeploy, err := workloads.RequestDeployment(deployReq) + desired, err := workloads.RequestDeployment(req) if err != nil { - return errors.Wrapf(err, "reconcileDeployment: failed to reconcile deployment %s", desiredDeploy.Name) + return errors.Wrapf(err, "reconcileDeployment: failed to reconcile deployment %s", desired.Name) } - if err = controllerutil.SetControllerReference(rsr.Instance, desiredDeploy, rsr.Scheme); err != nil { - rsr.Logger.Error(err, "reconcileDeployment: failed to set owner reference for deployment", "name", desiredDeploy.Name, "namespace", desiredDeploy.Namespace) + if err = controllerutil.SetControllerReference(rsr.Instance, desired, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileDeployment: failed to set owner reference for deployment", "name", desired.Name, "namespace", desired.Namespace) } - existingDeploy, err := workloads.GetDeployment(desiredDeploy.Name, desiredDeploy.Namespace, rsr.Client) + existing, err := workloads.GetDeployment(desired.Name, desired.Namespace, rsr.Client) if err != nil { if !apierrors.IsNotFound(err) { - return errors.Wrapf(err, "reconcileDeployment: failed to retrieve deployment %s", desiredDeploy.Name) + return errors.Wrapf(err, "reconcileDeployment: failed to retrieve deployment %s", desired.Name) } - if err = workloads.CreateDeployment(desiredDeploy, rsr.Client); err != nil { - return errors.Wrapf(err, "reconcileDeployment: failed to create deployment %s in namespace %s", desiredDeploy.Name, desiredDeploy.Namespace) + if err = workloads.CreateDeployment(desired, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileDeployment: failed to create deployment %s in namespace %s", desired.Name, desired.Namespace) } - rsr.Logger.Info("deployment created", "name", desiredDeploy.Name, "namespace", desiredDeploy.Namespace) + rsr.Logger.Info("deployment created", "name", desired.Name, "namespace", desired.Namespace) return nil } - deployChanged := false + changed := false - fieldsToCompare := []struct { - existing, desired interface{} - extraAction func() - }{ - {&existingDeploy.Spec.Template.Spec.Containers[0].Image, &desiredDeploy.Spec.Template.Spec.Containers[0].Image, - func() { - if existingDeploy.Spec.Template.ObjectMeta.Labels == nil { - existingDeploy.Spec.Template.ObjectMeta.Labels = map[string]string{} + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existing.Spec.Template.Spec.Containers[0].Image, Desired: &desired.Spec.Template.Spec.Containers[0].Image, + ExtraAction: func() { + if existing.Spec.Template.ObjectMeta.Labels == nil { + existing.Spec.Template.ObjectMeta.Labels = map[string]string{} } - existingDeploy.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) + existing.Spec.Template.ObjectMeta.Labels[common.ImageUpgradedKey] = time.Now().UTC().Format(common.TimeFormatMST) }, }, - {&existingDeploy.Spec.Template.Spec.NodeSelector, &desiredDeploy.Spec.Template.Spec.NodeSelector, nil}, - {&existingDeploy.Spec.Template.Spec.Tolerations, &desiredDeploy.Spec.Template.Spec.Tolerations, nil}, - {&existingDeploy.Spec.Template.Spec.Volumes, &desiredDeploy.Spec.Template.Spec.Volumes, nil}, - {&existingDeploy.Spec.Template.Spec.Containers[0].Command, &desiredDeploy.Spec.Template.Spec.Containers[0].Command, nil}, - {&existingDeploy.Spec.Template.Spec.Containers[0].Env, &desiredDeploy.Spec.Template.Spec.Containers[0].Env, nil}, - {&existingDeploy.Spec.Template.Spec.Containers[0].Resources, &desiredDeploy.Spec.Template.Spec.Containers[0].Resources, nil}, - {&existingDeploy.Spec.Template.Spec.Containers[0].VolumeMounts, &desiredDeploy.Spec.Template.Spec.Containers[0].VolumeMounts, nil}, - {&existingDeploy.Spec.Template.Spec.InitContainers, &desiredDeploy.Spec.Template.Spec.InitContainers, nil}, - {&existingDeploy.Spec.Template.Spec.AutomountServiceAccountToken, &desiredDeploy.Spec.Template.Spec.AutomountServiceAccountToken, nil}, - {&existingDeploy.Spec.Template.Spec.ServiceAccountName, &desiredDeploy.Spec.Template.Spec.ServiceAccountName, nil}, - {&existingDeploy.Spec.Replicas, &desiredDeploy.Spec.Replicas, nil}, + {Existing: &existing.Spec.Template.Spec.NodeSelector, Desired: &desired.Spec.Template.Spec.NodeSelector, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.Tolerations, Desired: &desired.Spec.Template.Spec.Tolerations, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.Volumes, Desired: &desired.Spec.Template.Spec.Volumes, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.Containers[0].Command, Desired: &desired.Spec.Template.Spec.Containers[0].Command, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.Containers[0].Env, Desired: &desired.Spec.Template.Spec.Containers[0].Env, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.Containers[0].Resources, Desired: &desired.Spec.Template.Spec.Containers[0].Resources, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.Containers[0].VolumeMounts, Desired: &desired.Spec.Template.Spec.Containers[0].VolumeMounts, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.InitContainers, Desired: &desired.Spec.Template.Spec.InitContainers, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.AutomountServiceAccountToken, Desired: &desired.Spec.Template.Spec.AutomountServiceAccountToken, ExtraAction: nil}, + {Existing: &existing.Spec.Template.Spec.ServiceAccountName, Desired: &desired.Spec.Template.Spec.ServiceAccountName, ExtraAction: nil}, + {Existing: &existing.Spec.Replicas, Desired: &desired.Spec.Replicas, ExtraAction: nil}, + {Existing: &existing.Labels, Desired: &desired.Labels, ExtraAction: nil}, + {Existing: &existing.Annotations, Desired: &desired.Annotations, ExtraAction: nil}, } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &deployChanged) - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &changed) - if !reflect.DeepEqual(desiredDeploy.Spec.Template.Spec.Containers[1:], existingDeploy.Spec.Template.Spec.Containers[1:]) { - existingDeploy.Spec.Template.Spec.Containers = append(existingDeploy.Spec.Template.Spec.Containers[0:1], - desiredDeploy.Spec.Template.Spec.Containers[1:]...) - deployChanged = true + if !reflect.DeepEqual(desired.Spec.Template.Spec.Containers[1:], existing.Spec.Template.Spec.Containers[1:]) { + existing.Spec.Template.Spec.Containers = append(existing.Spec.Template.Spec.Containers[0:1], + desired.Spec.Template.Spec.Containers[1:]...) + changed = true } - if !deployChanged { + if !changed { return nil } - if err = workloads.UpdateDeployment(existingDeploy, rsr.Client); err != nil { - return errors.Wrapf(err, "reconcileDeployment: failed to update deployment %s", existingDeploy.Name) + if err = workloads.UpdateDeployment(existing, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileDeployment: failed to update deployment %s", existing.Name) } - rsr.Logger.Info("deployment updated", "name", existingDeploy.Name, "namespace", existingDeploy.Namespace) + rsr.Logger.Info("deployment updated", "name", existing.Name, "namespace", existing.Namespace) return nil } func (rsr *RepoServerReconciler) getDeploymentRequest() workloads.DeploymentRequest { - deploymentReq := workloads.DeploymentRequest{ + req := workloads.DeploymentRequest{ ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), Spec: appsv1.DeploymentSpec{ Selector: &metav1.LabelSelector{ @@ -111,6 +108,7 @@ func (rsr *RepoServerReconciler) getDeploymentRequest() workloads.DeploymentRequ common.AppK8sKeyName: resourceName, }, }, + Replicas: rsr.getReplicas(), Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -136,21 +134,21 @@ func (rsr *RepoServerReconciler) getDeploymentRequest() workloads.DeploymentRequ } if rsr.Instance.Spec.Repo.ServiceAccount != "" { - deploymentReq.Spec.Template.Spec.ServiceAccountName = rsr.Instance.Spec.Repo.ServiceAccount + req.Spec.Template.Spec.ServiceAccountName = rsr.Instance.Spec.Repo.ServiceAccount } if rsr.Instance.Spec.NodePlacement != nil { - deploymentReq.Spec.Template.Spec.NodeSelector = util.MergeMaps(deploymentReq.Spec.Template.Spec.NodeSelector, rsr.Instance.Spec.NodePlacement.NodeSelector) - deploymentReq.Spec.Template.Spec.Tolerations = rsr.Instance.Spec.NodePlacement.Tolerations + req.Spec.Template.Spec.NodeSelector = util.MergeMaps(req.Spec.Template.Spec.NodeSelector, rsr.Instance.Spec.NodePlacement.NodeSelector) + req.Spec.Template.Spec.Tolerations = rsr.Instance.Spec.NodePlacement.Tolerations } - return deploymentReq + return req } func (rsr *RepoServerReconciler) getRepoSeverInitContainers() []corev1.Container { initContainers := []corev1.Container{{ Name: "copyutil", - Image: argocdcommon.GetArgoContainerImage(rsr.Instance), + Image: rsr.getContainerImage(), Command: argocdcommon.GetArgoCmpServerInitCommand(), ImagePullPolicy: corev1.PullAlways, Resources: rsr.getResources(), diff --git a/controllers/argocd/reposerver/helper.go b/controllers/argocd/reposerver/helper.go index 298253490..29158cbbc 100644 --- a/controllers/argocd/reposerver/helper.go +++ b/controllers/argocd/reposerver/helper.go @@ -39,11 +39,11 @@ func (rsr *RepoServerReconciler) getContainerImage() string { // GetServerAddress will return the repo-server service address for the given ArgoCD instance func (rsr *RepoServerReconciler) GetServerAddress() string { - if rsr.Instance.Spec.Redis.Remote != nil && *rsr.Instance.Spec.Redis.Remote != "" { - return *rsr.Instance.Spec.Redis.Remote + if rsr.Instance.Spec.Repo.Remote != nil && *rsr.Instance.Spec.Repo.Remote != "" { + return *rsr.Instance.Spec.Repo.Remote } - return argoutil.FqdnServiceRef(resourceName, rsr.Instance.Namespace, common.DefaultRedisPort) + return argoutil.FqdnServiceRef(resourceName, rsr.Instance.Namespace, common.DefaultRepoServerPort) } // getReplicas will return the size value for the argocd-repo-server replica count if it diff --git a/controllers/argocd/reposerver/service.go b/controllers/argocd/reposerver/service.go index 1e58c1387..0186e7fb7 100644 --- a/controllers/argocd/reposerver/service.go +++ b/controllers/argocd/reposerver/service.go @@ -18,7 +18,7 @@ import ( ) func (rsr *RepoServerReconciler) reconcileService() error { - svcRequest := networking.ServiceRequest{ + req := networking.ServiceRequest{ ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ @@ -48,52 +48,47 @@ func (rsr *RepoServerReconciler) reconcileService() error { Client: rsr.Client, } - desiredSvc, err := networking.RequestService(svcRequest) + desired, err := networking.RequestService(req) if err != nil { - return errors.Wrapf(err, "reconcileService: failed to request service %s", desiredSvc.Name) + return errors.Wrapf(err, "reconcileService: failed to request service %s", desired.Name) } - if err = controllerutil.SetControllerReference(rsr.Instance, desiredSvc, rsr.Scheme); err != nil { - rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desiredSvc.Name) + if err = controllerutil.SetControllerReference(rsr.Instance, desired, rsr.Scheme); err != nil { + rsr.Logger.Error(err, "reconcileService: failed to set owner reference for service", "name", desired.Name) } - existingSvc, err := networking.GetService(desiredSvc.Name, desiredSvc.Namespace, rsr.Client) + existing, err := networking.GetService(desired.Name, desired.Namespace, rsr.Client) if err != nil { if !apierrors.IsNotFound(err) { - return errors.Wrapf(err, "reconcileService: failed to retrieve service %s", desiredSvc.Name) + return errors.Wrapf(err, "reconcileService: failed to retrieve service %s", desired.Name) } - if err = networking.CreateService(desiredSvc, rsr.Client); err != nil { - return errors.Wrapf(err, "reconcileService: failed to create service %s", desiredSvc.Name) + if err = networking.CreateService(desired, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileService: failed to create service %s", desired.Name) } - rsr.Logger.Info("service created", "name", desiredSvc.Name, "namespace", desiredSvc.Namespace) + rsr.Logger.Info("service created", "name", desired.Name, "namespace", desired.Namespace) return nil } - svcChanged := false + changed := false - fieldsToCompare := []struct { - existing, desired interface{} - extraAction func() - }{ - {&existingSvc.Labels, &desiredSvc.Labels, nil}, - {&existingSvc.Annotations, &desiredSvc.Annotations, nil}, - {&existingSvc.Spec, &desiredSvc.Spec, nil}, + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existing.Labels, Desired: &desired.Labels, ExtraAction: nil}, + {Existing: &existing.Annotations, Desired: &desired.Annotations, ExtraAction: nil}, + {Existing: &existing.Spec, Desired: &desired.Spec, ExtraAction: nil}, } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &svcChanged) - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &changed) - if !svcChanged { + if !changed { return nil } - if err = networking.UpdateService(existingSvc, rsr.Client); err != nil { - return errors.Wrapf(err, "reconcileService: failed to update service %s", existingSvc.Name) + if err = networking.UpdateService(existing, rsr.Client); err != nil { + return errors.Wrapf(err, "reconcileService: failed to update service %s", existing.Name) } - rsr.Logger.Info("service updated", "name", existingSvc.Name, "namespace", existingSvc.Namespace) + rsr.Logger.Info("service updated", "name", existing.Name, "namespace", existing.Namespace) return nil } diff --git a/controllers/argocd/reposerver/serviceaccount.go b/controllers/argocd/reposerver/serviceaccount.go index 2ade4a4b1..1907ecb28 100644 --- a/controllers/argocd/reposerver/serviceaccount.go +++ b/controllers/argocd/reposerver/serviceaccount.go @@ -10,26 +10,26 @@ import ( func (rsr *RepoServerReconciler) reconcileServiceAccount() error { - saReq := permissions.ServiceAccountRequest{ + req := permissions.ServiceAccountRequest{ ObjectMeta: argoutil.GetObjMeta(resourceName, rsr.Instance.Namespace, rsr.Instance.Name, rsr.Instance.Namespace, component), } - desiredSa := permissions.RequestServiceAccount(saReq) + desired := permissions.RequestServiceAccount(req) - if err := controllerutil.SetControllerReference(rsr.Instance, desiredSa, rsr.Scheme); err != nil { + if err := controllerutil.SetControllerReference(rsr.Instance, desired, rsr.Scheme); err != nil { rsr.Logger.Error(err, "reconcileServiceAccount: failed to set owner reference for serviceaccount") } - _, err := permissions.GetServiceAccount(desiredSa.Name, desiredSa.Namespace, rsr.Client) + _, err := permissions.GetServiceAccount(desired.Name, desired.Namespace, rsr.Client) if err != nil { if !apierrors.IsNotFound(err) { return errors.Wrapf(err, "reconcileServiceAccount: failed to retrieve serviceaccount") } - if err = permissions.CreateServiceAccount(desiredSa, rsr.Client); err != nil { + if err = permissions.CreateServiceAccount(desired, rsr.Client); err != nil { return errors.Wrapf(err, "reconcileServiceAccount: failed to create serviceaccount") } - rsr.Logger.Info("serviceaccount created", "name", desiredSa.Name, "namespace", desiredSa.Namespace) + rsr.Logger.Info("serviceaccount created", "name", desired.Name, "namespace", desired.Namespace) return nil } return nil diff --git a/controllers/argocd/reposerver/servicemonitor.go b/controllers/argocd/reposerver/servicemonitor.go index bcaa3d57c..e86fdd58d 100644 --- a/controllers/argocd/reposerver/servicemonitor.go +++ b/controllers/argocd/reposerver/servicemonitor.go @@ -63,18 +63,13 @@ func (rsr *RepoServerReconciler) reconcileServiceMonitor() error { changed := false - fieldsToCompare := []struct { - existing, desired interface{} - extraAction func() - }{ - {&existing.Labels, &desired.Labels, nil}, - {&existing.Annotations, &desired.Annotations, nil}, - {&existing.Spec, &desired.Spec, nil}, + fieldsToCompare := []argocdcommon.FieldToCompare{ + {Existing: &existing.Labels, Desired: &desired.Labels, ExtraAction: nil}, + {Existing: &existing.Annotations, Desired: &desired.Annotations, ExtraAction: nil}, + {Existing: &existing.Spec, Desired: &desired.Spec, ExtraAction: nil}, } - for _, field := range fieldsToCompare { - argocdcommon.UpdateIfChanged(field.existing, field.desired, field.extraAction, &changed) - } + argocdcommon.UpdateIfChanged(fieldsToCompare, &changed) if !changed { return nil From bc27d5c9514c3bd695d66423145fd1aa3dec89e1 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 01:53:45 -0500 Subject: [PATCH 79/94] add helper unit tests Signed-off-by: Jaideep Rao --- controllers/argocd/argocd_controller.go | 4 +- controllers/argocd/reposerver/helper_test.go | 255 +++++++++++++++++++ controllers/argocd/reposerver/status.go | 15 +- go.mod | 1 - go.sum | 1 - pkg/util/string.go | 5 + 6 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 controllers/argocd/reposerver/helper_test.go diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index fa23b0574..4d629de1e 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -393,12 +393,13 @@ func (r *ArgoCDReconciler) reconcileControllers() error { return err } - if *r.Instance.Spec.Repo.Enabled { + if r.Instance.Spec.Repo.Enabled != nil && *r.Instance.Spec.Repo.Enabled { if err := r.ReposerverController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile repo-server controller") return err } } else { + r.Logger.Info("repo-server disabled; deleting resources") if err := r.ReposerverController.DeleteResources(); err != nil { r.Logger.Error(err, "failed to delete repo-server resources") } @@ -451,6 +452,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, + Logger: util.NewLogger(common.RedisController, "instance", r.Instance.Name, "instance-namespace", r.Instance.Namespace), } reposerverController := &reposerver.RepoServerReconciler{ diff --git a/controllers/argocd/reposerver/helper_test.go b/controllers/argocd/reposerver/helper_test.go new file mode 100644 index 000000000..00c3e366b --- /dev/null +++ b/controllers/argocd/reposerver/helper_test.go @@ -0,0 +1,255 @@ +package reposerver + +import ( + "os" + "testing" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/test" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" +) + +func TestTLSVerificationRequested(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedResult bool + }{ + { + name: "TLS Verification Requested", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Repo.VerifyTLS = true + }, + ), + ), + expectedResult: true, + }, + { + name: "TLS Verification Not Requested", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Repo.VerifyTLS = false + }, + ), + ), + expectedResult: false, + }, + { + name: "Default (TLS Verification Not Specified)", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedResult: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.reconciler.TLSVerificationRequested() + assert.Equal(t, tt.expectedResult, result) + }) + } +} + +func TestGetResources(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedResult corev1.ResourceRequirements + }{ + { + name: "Resource Requirements Specified", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Repo.Resources = &corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("200m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), + }, + } + }, + ), + ), + expectedResult: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("256Mi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("200m"), + corev1.ResourceMemory: resource.MustParse("512Mi"), + }, + }, + }, + { + name: "Default (Resource Requirements Not Specified)", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedResult: corev1.ResourceRequirements{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.reconciler.getResources() + assert.Equal(t, tt.expectedResult, result) + }) + } +} + +func TestGetContainerImage(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + setEnvVarFunc func() + UnsetEnvVarFunc func() + expectedResult string + }{ + { + name: "CR Spec Specifies Image", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Repo.Image = "custom-image" + cr.Spec.Repo.Version = "custom-version" + }, + ), + ), + setEnvVarFunc: func() { + os.Setenv("ARGOCD_IMAGE", "default-argocd-img:v1.0") + }, + UnsetEnvVarFunc: func() { + os.Unsetenv("ARGOCD_IMAGE") + }, + expectedResult: "custom-image:custom-version", + }, + { + name: "Env Var Specifies Image", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + setEnvVarFunc: func() { + os.Setenv("ARGOCD_IMAGE", "default-argocd-img:v1.0") + }, + UnsetEnvVarFunc: func() { + os.Unsetenv("ARGOCD_IMAGE") + }, + expectedResult: "default-argocd-img:v1.0", + }, + { + name: "Default Image and Tag Used", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + setEnvVarFunc: nil, + expectedResult: "quay.io/argoproj/argocd@sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Set environment variable if specified + if tt.setEnvVarFunc != nil { + tt.setEnvVarFunc() + defer tt.UnsetEnvVarFunc() + } + + result := tt.reconciler.getContainerImage() + assert.Equal(t, tt.expectedResult, result) + }) + } +} + +func TestGetServerAddress(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedResult string + }{ + { + name: "Custom Remote Specified", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Repo.Remote = util.StringPtr("https://custom.repo.server") + }, + ), + ), + expectedResult: "https://custom.repo.server", + }, + { + name: "Default (Remote Not Specified)", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedResult: "test-argocd-repo-server.test-ns.svc.cluster.local:8081", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.reconciler.varSetter() + result := tt.reconciler.GetServerAddress() + assert.Equal(t, tt.expectedResult, result) + }) + } +} + +func TestGetReplicas(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedResult *int32 + }{ + { + name: "Replicas Specified", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + replicas := int32(3) + cr.Spec.Repo.Replicas = &replicas + }, + ), + ), + expectedResult: util.Int32Ptr(3), + }, + { + name: "Negative Replicas Specified", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + replicas := int32(-1) + cr.Spec.Repo.Replicas = &replicas + }, + ), + ), + expectedResult: nil, + }, + { + name: "Default (Replicas Not Specified)", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedResult: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.reconciler.getReplicas() + assert.Equal(t, tt.expectedResult, result) + }) + } +} diff --git a/controllers/argocd/reposerver/status.go b/controllers/argocd/reposerver/status.go index 760797a28..f01bf9a42 100644 --- a/controllers/argocd/reposerver/status.go +++ b/controllers/argocd/reposerver/status.go @@ -6,6 +6,7 @@ import ( "github.com/argoproj-labs/argocd-operator/common" "github.com/argoproj-labs/argocd-operator/pkg/workloads" "github.com/pkg/errors" + "k8s.io/client-go/util/retry" ) // reconcileStatus will ensure that the Repo-server status is updated for the given ArgoCD instance @@ -33,8 +34,18 @@ func (rsr *RepoServerReconciler) reconcileStatus() error { } func (rsr *RepoServerReconciler) UpdateInstanceStatus() error { - if err := rsr.Client.Status().Update(context.TODO(), rsr.Instance); err != nil { - return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := rsr.Client.Status().Update(context.TODO(), rsr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err } return nil } diff --git a/go.mod b/go.mod index cb0fb4072..1dd89fff6 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,6 @@ require ( github.com/prometheus/procfs v0.10.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect diff --git a/go.sum b/go.sum index e94e3e94b..014c29c9f 100644 --- a/go.sum +++ b/go.sum @@ -1787,7 +1787,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= diff --git a/pkg/util/string.go b/pkg/util/string.go index f456e8d69..cc50bed6d 100644 --- a/pkg/util/string.go +++ b/pkg/util/string.go @@ -68,3 +68,8 @@ func GenerateRandomString(s int) (string, error) { } return base64.URLEncoding.EncodeToString(b), nil } + +// StringPtr returns a pointer to provided string value +func StringPtr(val string) *string { + return &val +} From b2400f91e85f9b1e9e48831e43a0c0e6bdd6cde1 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:09:58 -0500 Subject: [PATCH 80/94] add unit tests for resource deletion & trigger rollout Signed-off-by: Jaideep Rao --- controllers/argocd/argocdcommon/workloads.go | 4 + controllers/argocd/reposerver/reposerver.go | 1 + .../argocd/reposerver/reposerver_test.go | 166 +++++++++++++++++- pkg/resource/helper.go | 30 ++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 pkg/resource/helper.go diff --git a/controllers/argocd/argocdcommon/workloads.go b/controllers/argocd/argocdcommon/workloads.go index 46d7585e2..86d56e51a 100644 --- a/controllers/argocd/argocdcommon/workloads.go +++ b/controllers/argocd/argocdcommon/workloads.go @@ -13,6 +13,10 @@ func TriggerDeploymentRollout(name, namespace, key string, client cntrlClient.Cl return err } + if deployment.Spec.Template.ObjectMeta.Labels == nil { + deployment.Spec.Template.ObjectMeta.Labels = make(map[string]string) + } + deployment.Spec.Template.ObjectMeta.Labels[key] = util.NowNano() return workloads.UpdateDeployment(deployment, client) } diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 3b28669cc..ca3922f92 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -70,6 +70,7 @@ func (rsr *RepoServerReconciler) Reconcile() error { return nil } +// DeleteResources triggers deletion of all repo-server resources func (rsr *RepoServerReconciler) DeleteResources() error { var deletionErr util.MultiError diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index 81710e9d7..5f91d9ecc 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -1,23 +1,32 @@ package reposerver import ( + "testing" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/common" + "github.com/argoproj-labs/argocd-operator/pkg/monitoring" + "github.com/argoproj-labs/argocd-operator/pkg/resource" "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/pkg/workloads" "github.com/argoproj-labs/argocd-operator/tests/test" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) -func makeTestReposerverReconciler(cr *argoproj.ArgoCD, objs ...runtime.Object) *RepoServerReconciler { +func makeTestReposerverReconciler(cr *argoproj.ArgoCD, objs ...client.Object) *RepoServerReconciler { schemeOpt := func(s *runtime.Scheme) { monitoringv1.AddToScheme(s) argoproj.AddToScheme(s) } sch := test.MakeTestReconcilerScheme(schemeOpt) - client := test.MakeTestReconcilerClient(sch, []client.Object{}, []client.Object{}, objs) + client := test.MakeTestReconcilerClient(sch, objs, []client.Object{}, []runtime.Object{}) return &RepoServerReconciler{ Client: client, @@ -26,3 +35,156 @@ func makeTestReposerverReconciler(cr *argoproj.ArgoCD, objs ...runtime.Object) * Logger: util.NewLogger(common.RepoServerController), } } + +func TestDeleteResources(t *testing.T) { + tests := []struct { + name string + resources []client.Object + prometheusAPIAvailable bool + expectedErrors []string + }{ + { + name: "Prometheus API available", + resources: []client.Object{ + test.MakeTestServiceAccount( + func(sa *corev1.ServiceAccount) { + sa.Name = resourceName + }, + ), + test.MakeTestService( + func(s *corev1.Service) { + s.Name = resourceName + }, + ), + test.MakeTestServiceMonitor( + func(sm *monitoringv1.ServiceMonitor) { + sm.Name = resourceMetricsName + }, + ), + test.MakeTestSecret( + func(sec *corev1.Secret) { + sec.Name = common.ArgoCDRepoServerTLSSecretName + }, + ), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = resourceName + }, + ), + }, + prometheusAPIAvailable: true, + expectedErrors: nil, + }, + { + name: "Prometheus API not available", + resources: []client.Object{ + test.MakeTestServiceAccount( + func(sa *corev1.ServiceAccount) { + sa.Name = resourceName + }, + ), + test.MakeTestService( + func(s *corev1.Service) { + s.Name = resourceName + }, + ), + test.MakeTestSecret( + func(sec *corev1.Secret) { + sec.Name = common.ArgoCDRepoServerTLSSecretName + }, + ), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = resourceName + }, + ), + }, + prometheusAPIAvailable: false, + expectedErrors: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + reconciler := makeTestReposerverReconciler( + test.MakeTestArgoCD(), + tt.resources..., + ) + + reconciler.varSetter() + + monitoring.SetPrometheusAPIFound(tt.prometheusAPIAvailable) + defer monitoring.SetPrometheusAPIFound(false) + + err := reconciler.DeleteResources() + + if len(tt.expectedErrors) > 0 { + assert.Error(t, err, "Expected an error but got none.") + for _, expectedError := range tt.expectedErrors { + assert.Contains(t, err.Error(), expectedError, "Error message did not contain the expected substring.") + } + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + for _, obj := range tt.resources { + _, err := resource.GetObject(resourceName, test.TestNamespace, obj, reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + } + }) + } +} + +func TestTriggerRollout(t *testing.T) { + tests := []struct { + name string + reconciler *RepoServerReconciler + deploymentexists bool + expectedError bool + }{ + { + name: "Deployment exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = "test-argocd-repo-server" + }, + ), + ), + deploymentexists: true, + expectedError: false, + }, + { + name: "Deployment does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + deploymentexists: false, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.reconciler.varSetter() + + err := tt.reconciler.TriggerRollout(test.TestKey) + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + if !tt.expectedError { + dep, err := workloads.GetDeployment(resourceName, test.TestNamespace, tt.reconciler.Client) + assert.NoError(t, err) + + _, ok := dep.Spec.Template.ObjectMeta.Labels[test.TestKey] + assert.True(t, ok) + } + + }) + } +} diff --git a/pkg/resource/helper.go b/pkg/resource/helper.go new file mode 100644 index 000000000..edf2e8011 --- /dev/null +++ b/pkg/resource/helper.go @@ -0,0 +1,30 @@ +package resource + +import ( + "github.com/argoproj-labs/argocd-operator/pkg/util" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func ConvertToRuntimeObjects(objs ...client.Object) ([]runtime.Object, error) { + runtimeObjs := []runtime.Object{} + var conversaionErr util.MultiError + + for _, obj := range objs { + // Get the GVK (GroupVersionKind) of the client.Object + gvk := obj.GetObjectKind().GroupVersionKind() + + // Create a new empty runtime.Object with the same GVK + newRuntimeObject, err := scheme.Scheme.New(gvk) + conversaionErr.Append(err) + + // DeepCopy the client.Object into the runtime.Object + err = scheme.Scheme.Convert(obj, newRuntimeObject, nil) + conversaionErr.Append(err) + + runtimeObjs = append(runtimeObjs, newRuntimeObject) + } + + return runtimeObjs, conversaionErr.ErrOrNil() +} From 1061a4f7c354bb35b5650080cdca7510b176f170 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:15:54 -0500 Subject: [PATCH 81/94] add resource helper & updated trigger rollout Signed-off-by: Jaideep Rao --- controllers/argocd/argocdcommon/workloads.go | 4 +++ pkg/resource/helper.go | 30 ++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 pkg/resource/helper.go diff --git a/controllers/argocd/argocdcommon/workloads.go b/controllers/argocd/argocdcommon/workloads.go index 46d7585e2..86d56e51a 100644 --- a/controllers/argocd/argocdcommon/workloads.go +++ b/controllers/argocd/argocdcommon/workloads.go @@ -13,6 +13,10 @@ func TriggerDeploymentRollout(name, namespace, key string, client cntrlClient.Cl return err } + if deployment.Spec.Template.ObjectMeta.Labels == nil { + deployment.Spec.Template.ObjectMeta.Labels = make(map[string]string) + } + deployment.Spec.Template.ObjectMeta.Labels[key] = util.NowNano() return workloads.UpdateDeployment(deployment, client) } diff --git a/pkg/resource/helper.go b/pkg/resource/helper.go new file mode 100644 index 000000000..f74e326aa --- /dev/null +++ b/pkg/resource/helper.go @@ -0,0 +1,30 @@ +package resource + +import ( + "github.com/argoproj-labs/argocd-operator/pkg/util" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func ConvertToRuntimeObjects(objs ...client.Object) ([]runtime.Object, error) { + runtimeObjs := []runtime.Object{} + var conversionErr util.MultiError + + for _, obj := range objs { + // Get the GVK (GroupVersionKind) of the client.Object + gvk := obj.GetObjectKind().GroupVersionKind() + + // Create a new empty runtime.Object with the same GVK + newRuntimeObject, err := scheme.Scheme.New(gvk) + conversionErr.Append(err) + + // DeepCopy the client.Object into the runtime.Object + err = scheme.Scheme.Convert(obj, newRuntimeObject, nil) + conversionErr.Append(err) + + runtimeObjs = append(runtimeObjs, newRuntimeObject) + } + + return runtimeObjs, conversionErr.ErrOrNil() +} From 923407a5fdb70135e0d04f244326cb3bb08e6b74 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:22:51 -0500 Subject: [PATCH 82/94] modify scheme opt signature Signed-off-by: Jaideep Rao --- tests/test/testing.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test/testing.go b/tests/test/testing.go index 46a1bbb4c..174ff8360 100644 --- a/tests/test/testing.go +++ b/tests/test/testing.go @@ -56,12 +56,12 @@ func MakeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client. return client.Build() } -type SchemeOpt func(*runtime.Scheme) error +type SchemeOpt func(*runtime.Scheme) func MakeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { s := scheme.Scheme for _, opt := range sOpts { - _ = opt(s) + opt(s) } return s From 0cee249c9ac4c7b7a1edfcaf86b40ff22b5b6150 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:35:56 -0500 Subject: [PATCH 83/94] add helpers Signed-off-by: Jaideep Rao --- pkg/resource/helper.go | 38 +++- tests/test/testing.go | 399 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 tests/test/testing.go diff --git a/pkg/resource/helper.go b/pkg/resource/helper.go index f74e326aa..aa9fb3275 100644 --- a/pkg/resource/helper.go +++ b/pkg/resource/helper.go @@ -1,12 +1,20 @@ package resource import ( + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/util" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + appsv1 "github.com/openshift/api/apps/v1" + configv1 "github.com/openshift/api/config/v1" + oauthv1 "github.com/openshift/api/oauth/v1" + routev1 "github.com/openshift/api/route/v1" + templatev1 "github.com/openshift/api/template/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" ) +// ConvertToRuntimeObjects converts a given set of client.Object resources into a slice of runtime.Objects func ConvertToRuntimeObjects(objs ...client.Object) ([]runtime.Object, error) { runtimeObjs := []runtime.Object{} var conversionErr util.MultiError @@ -15,12 +23,14 @@ func ConvertToRuntimeObjects(objs ...client.Object) ([]runtime.Object, error) { // Get the GVK (GroupVersionKind) of the client.Object gvk := obj.GetObjectKind().GroupVersionKind() + sch := GetScheme() + // Create a new empty runtime.Object with the same GVK - newRuntimeObject, err := scheme.Scheme.New(gvk) + newRuntimeObject, err := sch.New(gvk) conversionErr.Append(err) // DeepCopy the client.Object into the runtime.Object - err = scheme.Scheme.Convert(obj, newRuntimeObject, nil) + err = sch.Convert(obj, newRuntimeObject, nil) conversionErr.Append(err) runtimeObjs = append(runtimeObjs, newRuntimeObject) @@ -28,3 +38,27 @@ func ConvertToRuntimeObjects(objs ...client.Object) ([]runtime.Object, error) { return runtimeObjs, conversionErr.ErrOrNil() } + +func GetScheme() *runtime.Scheme { + sOpts := func(s *runtime.Scheme) { + argoproj.AddToScheme(s) + monitoringv1.AddToScheme(s) + routev1.Install(s) + configv1.Install(s) + templatev1.Install(s) + appsv1.Install(s) + oauthv1.Install(s) + } + return MakeScheme(sOpts) +} + +type SchemeOpt func(*runtime.Scheme) + +func MakeScheme(sOpts ...SchemeOpt) *runtime.Scheme { + s := scheme.Scheme + for _, opt := range sOpts { + opt(s) + } + + return s +} diff --git a/tests/test/testing.go b/tests/test/testing.go new file mode 100644 index 000000000..174ff8360 --- /dev/null +++ b/tests/test/testing.go @@ -0,0 +1,399 @@ +package test + +import ( + "errors" + + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + appsv1 "k8s.io/api/apps/v1" + autoscalingv1 "k8s.io/api/autoscaling/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" + cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +const ( + TestArgoCDName = "test-argocd" + TestName = "test-name" + TestInstance = "test-instance" + TestInstanceNamespace = "test-instance-ns" + TestNamespace = "test-ns" + TestComponent = "test-component" + TestApplicationName = "test-application-name" + TestKey = "test-key" + TestVal = "test-val" + TestValMutated = "test-val-mutated" + TestNameMutated = "test-name-mutated" +) + +var ( + TestKVP = map[string]string{ + TestKey: TestVal, + } + TestKVPMutated = map[string]string{ + TestKey: TestValMutated, + } +) + +func MakeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client.Object, runtimeObj []runtime.Object) client.Client { + client := fake.NewClientBuilder().WithScheme(sch) + if len(resObjs) > 0 { + client = client.WithObjects(resObjs...) + } + if len(subresObjs) > 0 { + client = client.WithStatusSubresource(subresObjs...) + } + if len(runtimeObj) > 0 { + client = client.WithRuntimeObjects(runtimeObj...) + } + return client.Build() +} + +type SchemeOpt func(*runtime.Scheme) + +func MakeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { + s := scheme.Scheme + for _, opt := range sOpts { + opt(s) + } + + return s +} + +func TestMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { + return errors.New("test-mutation-error") +} + +func TestMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { + return nil +} + +type argoCDOpt func(*argoproj.ArgoCD) + +func MakeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { + a := &argoproj.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestArgoCDName, + Namespace: TestNamespace, + }, + } + for _, o := range opts { + o(a) + } + return a +} + +type namespaceOpt func(*corev1.Namespace) + +func MakeTestNamespace(opts ...namespaceOpt) *corev1.Namespace { + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestNamespace, + Labels: make(map[string]string), + }, + } + for _, o := range opts { + o(ns) + } + return ns +} + +type statefulSetOpt func(*appsv1.StatefulSet) + +func MakeTestStatefulSet(opts ...statefulSetOpt) *appsv1.StatefulSet { + desiredStatefulSet := &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{}, + }, + } + + for _, opt := range opts { + opt(desiredStatefulSet) + } + return desiredStatefulSet +} + +type deploymentOpt func(*appsv1.Deployment) + +func MakeTestDeployment(opts ...deploymentOpt) *appsv1.Deployment { + d := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{}, + }, + } + for _, o := range opts { + o(d) + } + return d +} + +type hpaOpt func(*autoscalingv1.HorizontalPodAutoscaler) + +func MakeTestHPA(opts ...hpaOpt) *autoscalingv1.HorizontalPodAutoscaler { + hpa := &autoscalingv1.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: autoscalingv1.HorizontalPodAutoscalerSpec{}, + } + for _, o := range opts { + o(hpa) + } + return hpa +} + +type podOpt func(*corev1.Pod) + +func MakeTestPod(opts ...podOpt) *corev1.Pod { + p := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + }, + } + for _, o := range opts { + o(p) + } + return p +} + +type serviceOpt func(*corev1.Service) + +func MakeTestService(opts ...serviceOpt) *corev1.Service { + s := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(s) + } + return s +} + +type configMapOpt func(*corev1.ConfigMap) + +func MakeTestConfigMap(opts ...configMapOpt) *corev1.ConfigMap { + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Data: make(map[string]string), + } + for _, o := range opts { + o(cm) + } + return cm +} + +type secretOpt func(*corev1.Secret) + +func MakeTestSecret(opts ...secretOpt) *corev1.Secret { + s := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + StringData: map[string]string{}, + } + for _, o := range opts { + o(s) + } + return s +} + +type roleOpt func(*rbacv1.Role) + +func MakeTestRole(opts ...roleOpt) *rbacv1.Role { + r := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Rules: TestRules, + } + for _, o := range opts { + o(r) + } + return r +} + +func MakeTestRoleRef(name string) rbacv1.RoleRef { + return rbacv1.RoleRef{ + Kind: "Role", + Name: name, + APIGroup: "rbac.authorization.k8s.io", + } +} + +func MakeTestSubjects(subs ...types.NamespacedName) []rbacv1.Subject { + subjects := []rbacv1.Subject{} + + for _, subj := range subs { + subjects = append(subjects, rbacv1.Subject{ + Kind: rbacv1.ServiceAccountKind, + Name: subj.Name, + Namespace: subj.Namespace, + }) + } + return subjects +} + +var ( + TestRules = []rbacv1.PolicyRule{ + { + APIGroups: []string{ + "", + }, + Resources: []string{ + "pods", + }, + Verbs: []string{ + "create", + }, + }, + } +) + +type roleBindingOpt func(*rbacv1.RoleBinding) + +func MakeTestRoleBinding(opts ...roleBindingOpt) *rbacv1.RoleBinding { + rb := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(rb) + } + return rb +} + +type clusterRoleOpt func(*rbacv1.ClusterRole) + +func MakeTestClusterRole(opts ...clusterRoleOpt) *rbacv1.ClusterRole { + cr := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Rules: TestRules, + } + for _, o := range opts { + o(cr) + } + return cr +} + +type clusterRoleBindingOpt func(*rbacv1.ClusterRoleBinding) + +func MakeTestClusterRoleBinding(opts ...clusterRoleBindingOpt) *rbacv1.ClusterRoleBinding { + crb := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: TestName, + APIGroup: "rbac.authorization.k8s.io", + }, + } + for _, o := range opts { + o(crb) + } + return crb +} + +type serviceAccountOpt func(*corev1.ServiceAccount) + +func MakeTestServiceAccount(opts ...serviceAccountOpt) *corev1.ServiceAccount { + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(sa) + } + return sa +} + +type serviceMonitorOpt func(*monitoringv1.ServiceMonitor) + +func MakeTestServiceMonitor(opts ...serviceMonitorOpt) *monitoringv1.ServiceMonitor { + sm := &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: TestKVP, + }, + }, + } + for _, o := range opts { + o(sm) + } + return sm +} + +type prometheusRuleOpt func(*monitoringv1.PrometheusRule) + +func MakeTestPrometheusRule(opts ...prometheusRuleOpt) *monitoringv1.PrometheusRule { + pr := &monitoringv1.PrometheusRule{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } + for _, o := range opts { + o(pr) + } + return pr +} From 3e5b6143a45052ab73db945566bb83c94873b505 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:42:00 -0500 Subject: [PATCH 84/94] remove unnecessary changes Signed-off-by: Jaideep Rao --- .../argocd/notifications/rolebinding.go | 35 +- tests/test/testing.go | 399 ------------------ 2 files changed, 18 insertions(+), 416 deletions(-) delete mode 100644 tests/test/testing.go diff --git a/controllers/argocd/notifications/rolebinding.go b/controllers/argocd/notifications/rolebinding.go index c82903dc0..95824c207 100644 --- a/controllers/argocd/notifications/rolebinding.go +++ b/controllers/argocd/notifications/rolebinding.go @@ -47,7 +47,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { }, } - desiredRb := permissions.RequestRoleBinding(roleBindingRequest) + desiredRoleBinding := permissions.RequestRoleBinding(roleBindingRequest) namespace, err := cluster.GetNamespace(nr.Instance.Namespace, nr.Client) if err != nil { @@ -55,36 +55,36 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { return err } if namespace.DeletionTimestamp != nil { - if err := nr.deleteRole(desiredRb.Name, desiredRb.Namespace); err != nil { - nr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + if err := nr.deleteRole(desiredRoleBinding.Name, desiredRoleBinding.Namespace); err != nil { + nr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) } return err } - existingRb, err := permissions.GetRoleBinding(desiredRb.Name, desiredRb.Namespace, nr.Client) + existingRoleBinding, err := permissions.GetRoleBinding(desiredRoleBinding.Name, desiredRoleBinding.Namespace, nr.Client) if err != nil { if !apierrors.IsNotFound(err) { - nr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + nr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - if err = controllerutil.SetControllerReference(nr.Instance, desiredRb, nr.Scheme); err != nil { - nr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + if err = controllerutil.SetControllerReference(nr.Instance, desiredRoleBinding, nr.Scheme); err != nil { + nr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) } - if err = permissions.CreateRoleBinding(desiredRb, nr.Client); err != nil { - nr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + if err = permissions.CreateRoleBinding(desiredRoleBinding, nr.Client); err != nil { + nr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + nr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return nil } // if roleRef differs, we must delete the rolebinding as kubernetes does not allow updation of roleRef - if !reflect.DeepEqual(existingRb.RoleRef, desiredRb.RoleRef) { - nr.Logger.Info("detected drift in roleRef for rolebinding", "name", existingRb.Name, "namespace", existingRb.Namespace) + if !reflect.DeepEqual(existingRoleBinding.RoleRef, desiredRoleBinding.RoleRef) { + nr.Logger.Info("detected drift in roleRef for rolebinding", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) if err := nr.deleteRoleBinding(resourceName, nr.Instance.Namespace); err != nil { - return errors.Wrapf(err, "reconcileRoleBinding: unable to delete obsolete rolebinding %s", existingRb.Name) + return errors.Wrapf(err, "reconcileRoleBinding: unable to delete obsolete rolebinding %s", existingRoleBinding.Name) } return nil } @@ -92,7 +92,7 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { rbChanged := false fieldsToCompare := []argocdcommon.FieldToCompare{ - {Existing: &existingRb.Subjects, Desired: &desiredRb.Subjects, ExtraAction: nil}, + {Existing: &existingRoleBinding.Subjects, Desired: &desiredRoleBinding.Subjects, ExtraAction: nil}, } argocdcommon.UpdateIfChanged(fieldsToCompare, &rbChanged) @@ -101,11 +101,12 @@ func (nr *NotificationsReconciler) reconcileRoleBinding() error { return nil } - if err = permissions.UpdateRoleBinding(existingRb, nr.Client); err != nil { - return errors.Wrapf(err, "reconcileRoleBinding: failed to update role %s", existingRb.Name) + if err = permissions.UpdateRoleBinding(existingRoleBinding, nr.Client); err != nil { + return errors.Wrapf(err, "reconcileRoleBinding: failed to update role %s", existingRoleBinding.Name) } - nr.Logger.Info("rolebinding updated", "name", existingRb.Name, "namespace", existingRb.Namespace) + nr.Logger.Info("rolebinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + return nil } diff --git a/tests/test/testing.go b/tests/test/testing.go deleted file mode 100644 index 174ff8360..000000000 --- a/tests/test/testing.go +++ /dev/null @@ -1,399 +0,0 @@ -package test - -import ( - "errors" - - monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" - appsv1 "k8s.io/api/apps/v1" - autoscalingv1 "k8s.io/api/autoscaling/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "sigs.k8s.io/controller-runtime/pkg/client" - cntrlClient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -const ( - TestArgoCDName = "test-argocd" - TestName = "test-name" - TestInstance = "test-instance" - TestInstanceNamespace = "test-instance-ns" - TestNamespace = "test-ns" - TestComponent = "test-component" - TestApplicationName = "test-application-name" - TestKey = "test-key" - TestVal = "test-val" - TestValMutated = "test-val-mutated" - TestNameMutated = "test-name-mutated" -) - -var ( - TestKVP = map[string]string{ - TestKey: TestVal, - } - TestKVPMutated = map[string]string{ - TestKey: TestValMutated, - } -) - -func MakeTestReconcilerClient(sch *runtime.Scheme, resObjs, subresObjs []client.Object, runtimeObj []runtime.Object) client.Client { - client := fake.NewClientBuilder().WithScheme(sch) - if len(resObjs) > 0 { - client = client.WithObjects(resObjs...) - } - if len(subresObjs) > 0 { - client = client.WithStatusSubresource(subresObjs...) - } - if len(runtimeObj) > 0 { - client = client.WithRuntimeObjects(runtimeObj...) - } - return client.Build() -} - -type SchemeOpt func(*runtime.Scheme) - -func MakeTestReconcilerScheme(sOpts ...SchemeOpt) *runtime.Scheme { - s := scheme.Scheme - for _, opt := range sOpts { - opt(s) - } - - return s -} - -func TestMutationFuncFailed(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return errors.New("test-mutation-error") -} - -func TestMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, client cntrlClient.Client, args ...interface{}) error { - return nil -} - -type argoCDOpt func(*argoproj.ArgoCD) - -func MakeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { - a := &argoproj.ArgoCD{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestArgoCDName, - Namespace: TestNamespace, - }, - } - for _, o := range opts { - o(a) - } - return a -} - -type namespaceOpt func(*corev1.Namespace) - -func MakeTestNamespace(opts ...namespaceOpt) *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestNamespace, - Labels: make(map[string]string), - }, - } - for _, o := range opts { - o(ns) - } - return ns -} - -type statefulSetOpt func(*appsv1.StatefulSet) - -func MakeTestStatefulSet(opts ...statefulSetOpt) *appsv1.StatefulSet { - desiredStatefulSet := &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: appsv1.StatefulSetSpec{ - Selector: &metav1.LabelSelector{}, - }, - } - - for _, opt := range opts { - opt(desiredStatefulSet) - } - return desiredStatefulSet -} - -type deploymentOpt func(*appsv1.Deployment) - -func MakeTestDeployment(opts ...deploymentOpt) *appsv1.Deployment { - d := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{}, - }, - } - for _, o := range opts { - o(d) - } - return d -} - -type hpaOpt func(*autoscalingv1.HorizontalPodAutoscaler) - -func MakeTestHPA(opts ...hpaOpt) *autoscalingv1.HorizontalPodAutoscaler { - hpa := &autoscalingv1.HorizontalPodAutoscaler{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: autoscalingv1.HorizontalPodAutoscalerSpec{}, - } - for _, o := range opts { - o(hpa) - } - return hpa -} - -type podOpt func(*corev1.Pod) - -func MakeTestPod(opts ...podOpt) *corev1.Pod { - p := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - }, - } - for _, o := range opts { - o(p) - } - return p -} - -type serviceOpt func(*corev1.Service) - -func MakeTestService(opts ...serviceOpt) *corev1.Service { - s := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - for _, o := range opts { - o(s) - } - return s -} - -type configMapOpt func(*corev1.ConfigMap) - -func MakeTestConfigMap(opts ...configMapOpt) *corev1.ConfigMap { - cm := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Data: make(map[string]string), - } - for _, o := range opts { - o(cm) - } - return cm -} - -type secretOpt func(*corev1.Secret) - -func MakeTestSecret(opts ...secretOpt) *corev1.Secret { - s := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - StringData: map[string]string{}, - } - for _, o := range opts { - o(s) - } - return s -} - -type roleOpt func(*rbacv1.Role) - -func MakeTestRole(opts ...roleOpt) *rbacv1.Role { - r := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Rules: TestRules, - } - for _, o := range opts { - o(r) - } - return r -} - -func MakeTestRoleRef(name string) rbacv1.RoleRef { - return rbacv1.RoleRef{ - Kind: "Role", - Name: name, - APIGroup: "rbac.authorization.k8s.io", - } -} - -func MakeTestSubjects(subs ...types.NamespacedName) []rbacv1.Subject { - subjects := []rbacv1.Subject{} - - for _, subj := range subs { - subjects = append(subjects, rbacv1.Subject{ - Kind: rbacv1.ServiceAccountKind, - Name: subj.Name, - Namespace: subj.Namespace, - }) - } - return subjects -} - -var ( - TestRules = []rbacv1.PolicyRule{ - { - APIGroups: []string{ - "", - }, - Resources: []string{ - "pods", - }, - Verbs: []string{ - "create", - }, - }, - } -) - -type roleBindingOpt func(*rbacv1.RoleBinding) - -func MakeTestRoleBinding(opts ...roleBindingOpt) *rbacv1.RoleBinding { - rb := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - for _, o := range opts { - o(rb) - } - return rb -} - -type clusterRoleOpt func(*rbacv1.ClusterRole) - -func MakeTestClusterRole(opts ...clusterRoleOpt) *rbacv1.ClusterRole { - cr := &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Rules: TestRules, - } - for _, o := range opts { - o(cr) - } - return cr -} - -type clusterRoleBindingOpt func(*rbacv1.ClusterRoleBinding) - -func MakeTestClusterRoleBinding(opts ...clusterRoleBindingOpt) *rbacv1.ClusterRoleBinding { - crb := &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - RoleRef: rbacv1.RoleRef{ - Kind: "ClusterRole", - Name: TestName, - APIGroup: "rbac.authorization.k8s.io", - }, - } - for _, o := range opts { - o(crb) - } - return crb -} - -type serviceAccountOpt func(*corev1.ServiceAccount) - -func MakeTestServiceAccount(opts ...serviceAccountOpt) *corev1.ServiceAccount { - sa := &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - for _, o := range opts { - o(sa) - } - return sa -} - -type serviceMonitorOpt func(*monitoringv1.ServiceMonitor) - -func MakeTestServiceMonitor(opts ...serviceMonitorOpt) *monitoringv1.ServiceMonitor { - sm := &monitoringv1.ServiceMonitor{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: monitoringv1.ServiceMonitorSpec{ - Selector: metav1.LabelSelector{ - MatchLabels: TestKVP, - }, - }, - } - for _, o := range opts { - o(sm) - } - return sm -} - -type prometheusRuleOpt func(*monitoringv1.PrometheusRule) - -func MakeTestPrometheusRule(opts ...prometheusRuleOpt) *monitoringv1.PrometheusRule { - pr := &monitoringv1.PrometheusRule{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - } - for _, o := range opts { - o(pr) - } - return pr -} From 32f7d12788a8e4f597f1b722ba6f017f81f87b72 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:46:37 -0500 Subject: [PATCH 85/94] undo unneccesary appset changes Signed-off-by: Jaideep Rao --- .../argocd/applicationset/rolebinding.go | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/controllers/argocd/applicationset/rolebinding.go b/controllers/argocd/applicationset/rolebinding.go index 97971444e..e535bb80d 100644 --- a/controllers/argocd/applicationset/rolebinding.go +++ b/controllers/argocd/applicationset/rolebinding.go @@ -47,7 +47,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { }, } - desiredRb := permissions.RequestRoleBinding(roleBindingRequest) + desiredRoleBinding := permissions.RequestRoleBinding(roleBindingRequest) namespace, err := cluster.GetNamespace(asr.Instance.Namespace, asr.Client) if err != nil { @@ -55,36 +55,36 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { return err } if namespace.DeletionTimestamp != nil { - if err := asr.deleteRole(desiredRb.Name, desiredRb.Namespace); err != nil { - asr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + if err := asr.deleteRole(desiredRoleBinding.Name, desiredRoleBinding.Namespace); err != nil { + asr.Logger.Error(err, "reconcileRoleBinding: failed to delete roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) } return err } - existingRb, err := permissions.GetRoleBinding(desiredRb.Name, desiredRb.Namespace, asr.Client) + existingRoleBinding, err := permissions.GetRoleBinding(desiredRoleBinding.Name, desiredRoleBinding.Namespace, asr.Client) if err != nil { if !apierrors.IsNotFound(err) { - asr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + asr.Logger.Error(err, "reconcileRoleBinding: failed to retrieve roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - if err = controllerutil.SetControllerReference(asr.Instance, desiredRb, asr.Scheme); err != nil { - asr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + if err = controllerutil.SetControllerReference(asr.Instance, desiredRoleBinding, asr.Scheme); err != nil { + asr.Logger.Error(err, "reconcileRole: failed to set owner reference for role", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) } - if err = permissions.CreateRoleBinding(desiredRb, asr.Client); err != nil { - asr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + if err = permissions.CreateRoleBinding(desiredRoleBinding, asr.Client); err != nil { + asr.Logger.Error(err, "reconcileRoleBinding: failed to create roleBinding", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return err } - asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRb.Name, "namespace", desiredRb.Namespace) + asr.Logger.V(0).Info("reconcileRoleBinding: roleBinding created", "name", desiredRoleBinding.Name, "namespace", desiredRoleBinding.Namespace) return nil } // if roleRef differs, we must delete the rolebinding as kubernetes does not allow updation of roleRef - if !reflect.DeepEqual(existingRb.RoleRef, desiredRb.RoleRef) { - asr.Logger.Info("detected drift in roleRef for rolebinding", "name", existingRb.Name, "namespace", existingRb.Namespace) + if !reflect.DeepEqual(existingRoleBinding.RoleRef, desiredRoleBinding.RoleRef) { + asr.Logger.Info("detected drift in roleRef for rolebinding", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) if err := asr.deleteRoleBinding(resourceName, asr.Instance.Namespace); err != nil { - return errors.Wrapf(err, "reconcileRoleBinding: unable to delete obsolete rolebinding %s", existingRb.Name) + return errors.Wrapf(err, "reconcileRoleBinding: unable to delete obsolete rolebinding %s", existingRoleBinding.Name) } return nil } @@ -92,7 +92,7 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { rbChanged := false fieldsToCompare := []argocdcommon.FieldToCompare{ - {Existing: &existingRb.Subjects, Desired: &desiredRb.Subjects, ExtraAction: nil}, + {Existing: &existingRoleBinding.Subjects, Desired: &desiredRoleBinding.Subjects, ExtraAction: nil}, } argocdcommon.UpdateIfChanged(fieldsToCompare, &rbChanged) @@ -101,11 +101,12 @@ func (asr *ApplicationSetReconciler) reconcileRoleBinding() error { return nil } - if err = permissions.UpdateRoleBinding(existingRb, asr.Client); err != nil { - return errors.Wrapf(err, "reconcileRoleBinding: failed to update role %s", existingRb.Name) + if err = permissions.UpdateRoleBinding(existingRoleBinding, asr.Client); err != nil { + return errors.Wrapf(err, "reconcileRoleBinding: failed to update role %s", existingRoleBinding.Name) } - asr.Logger.Info("rolebinding updated", "name", existingRb.Name, "namespace", existingRb.Namespace) + asr.Logger.Info("rolebinding updated", "name", existingRoleBinding.Name, "namespace", existingRoleBinding.Namespace) + return nil } From e122612c94b07ffeeda58a84c787e79fd9f30626 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Sun, 28 Jan 2024 09:48:20 -0500 Subject: [PATCH 86/94] add nil check for ss Signed-off-by: Jaideep Rao --- controllers/argocd/argocdcommon/workloads.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/controllers/argocd/argocdcommon/workloads.go b/controllers/argocd/argocdcommon/workloads.go index 86d56e51a..197780f18 100644 --- a/controllers/argocd/argocdcommon/workloads.go +++ b/controllers/argocd/argocdcommon/workloads.go @@ -28,6 +28,10 @@ func TriggerStatefulSetRollout(name, namespace, key string, client cntrlClient.C return err } + if statefulset.Spec.Template.ObjectMeta.Labels == nil { + statefulset.Spec.Template.ObjectMeta.Labels = make(map[string]string) + } + statefulset.Spec.Template.ObjectMeta.Labels[key] = util.NowNano() return workloads.UpdateStatefulSet(statefulset, client) } From e19bf165a3b44b859ae2d455ad4750d31b5c6e6d Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 29 Jan 2024 06:10:28 -0500 Subject: [PATCH 87/94] wip: add unit tests with mocks Signed-off-by: Jaideep Rao --- controllers/argocd/reposerver/secret_test.go | 151 ++++++++++++++----- tests/mock/redis.go | 18 ++- tests/mock/reposerver.go | 10 +- 3 files changed, 137 insertions(+), 42 deletions(-) diff --git a/controllers/argocd/reposerver/secret_test.go b/controllers/argocd/reposerver/secret_test.go index df832b729..80fc9d490 100644 --- a/controllers/argocd/reposerver/secret_test.go +++ b/controllers/argocd/reposerver/secret_test.go @@ -3,8 +3,6 @@ package reposerver import ( "testing" - argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" - "github.com/argoproj-labs/argocd-operator/pkg/resource" "github.com/argoproj-labs/argocd-operator/pkg/workloads" "github.com/argoproj-labs/argocd-operator/tests/mock" "github.com/argoproj-labs/argocd-operator/tests/test" @@ -12,53 +10,134 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" ) func TestReconcileTLSSecret(t *testing.T) { mockServerName := "test-argocd-server" mockAppControllerName := "test-argocd-app-controller" - reconciler := makeTestReposerverReconciler( - test.MakeTestArgoCD(), - test.MakeTestSecret( - func(s *corev1.Secret) { - s.Name = "argocd-repo-server-tls" - s.Type = corev1.SecretTypeTLS - s.Data = map[string][]byte{ - "tls.crt": []byte(test.TestCert), - "tls.key": []byte(test.TestKey), - } - }, - ), - test.MakeTestDeployment( - func(d *appsv1.Deployment) { - d.Name = mockServerName + tests := []struct { + name string + resources []client.Object + secretExist bool + expectedError bool + }{ + { + name: "no TLS secret", + resources: []client.Object{ + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = mockServerName + }, + ), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = "test-argocd-repo-server" + }, + ), + test.MakeTestStatefulSet( + func(d *appsv1.StatefulSet) { + d.Name = mockAppControllerName + }, + ), }, - ), - test.MakeTestDeployment( - func(d *appsv1.Deployment) { - d.Name = "test-argocd-repo-server" + secretExist: false, + expectedError: false, + }, + { + name: "missing target deployments and statefulset", + resources: []client.Object{ + test.MakeTestSecret( + func(s *corev1.Secret) { + s.Name = "argocd-repo-server-tls" + s.Type = corev1.SecretTypeTLS + s.Data = map[string][]byte{ + "tls.crt": []byte(test.TestCert), + "tls.key": []byte(test.TestKey), + } + }, + ), }, - ), - test.MakeTestStatefulSet( - func(d *appsv1.StatefulSet) { - d.Name = mockAppControllerName + secretExist: true, + expectedError: true, + }, + { + name: "reconcile TLS secret", + resources: []client.Object{ + test.MakeTestSecret( + func(s *corev1.Secret) { + s.Name = "argocd-repo-server-tls" + s.Type = corev1.SecretTypeTLS + s.Data = map[string][]byte{ + "tls.crt": []byte(test.TestCert), + "tls.key": []byte(test.TestKey), + } + }, + ), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = mockServerName + }, + ), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = "test-argocd-repo-server" + }, + ), + test.MakeTestStatefulSet( + func(d *appsv1.StatefulSet) { + d.Name = mockAppControllerName + }, + ), }, - ), - ) + secretExist: true, + expectedError: false, + }, + } - reconciler.varSetter() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { - reconciler.Server = mock.NewServer(mockServerName, test.TestNamespace, reconciler.Client) - reconciler.Appcontroller = mock.NewAppController(mockAppControllerName, test.TestNamespace, reconciler.Client) + reconciler := makeTestReposerverReconciler( + test.MakeTestArgoCD(), + tt.resources..., + ) + reconciler.varSetter() - err := reconciler.reconcileTLSSecret() - assert.NoError(t, err) + reconciler.Server = mock.NewServer(mockServerName, test.TestNamespace, reconciler.Client) + reconciler.Appcontroller = mock.NewAppController(mockAppControllerName, test.TestNamespace, reconciler.Client) - res, err := resource.GetObject(test.TestArgoCDName, test.TestNamespace, &argoproj.ArgoCD{}, reconciler.Client) - argocd := res.(*argoproj.ArgoCD) - assert.NoError(t, err) - assert.NotEqual(t, "", argocd.Status.RepoTLSChecksum) + err := reconciler.reconcileTLSSecret() + if !tt.secretExist { + assert.NoError(t, err) + return + } + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + return + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + dep, err := workloads.GetDeployment(mockServerName, test.TestNamespace, reconciler.Client) + assert.NoError(t, err) + _, ok := dep.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"] + assert.True(t, ok) + + dep, err = workloads.GetDeployment(resourceName, test.TestNamespace, reconciler.Client) + assert.NoError(t, err) + _, ok = dep.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"] + assert.True(t, ok) + + ss, err := workloads.GetStatefulSet(mockAppControllerName, test.TestNamespace, reconciler.Client) + assert.NoError(t, err) + _, ok = ss.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"] + assert.True(t, ok) + + }) + } } func TestDeleteSecret(t *testing.T) { diff --git a/tests/mock/redis.go b/tests/mock/redis.go index de6319c38..da0999c42 100644 --- a/tests/mock/redis.go +++ b/tests/mock/redis.go @@ -1,7 +1,6 @@ package mock import ( - "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" "github.com/argoproj-labs/argocd-operator/pkg/util" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -13,6 +12,11 @@ type Redis struct { Namespace string } +var ( + useTLS = false + redisServerAddress = "" +) + func NewRedis(name, namespace string, client client.Client) *Redis { return &Redis{ Client: client, @@ -22,14 +26,18 @@ func NewRedis(name, namespace string, client client.Client) *Redis { } } -func (r *Redis) TriggerRollout(key string) error { - return argocdcommon.TriggerDeploymentRollout(r.Name, r.Namespace, key, r.Client) +func (r *Redis) SetUseTLS(val bool) { + useTLS = val +} + +func (r *Redis) SetServerAddress(val string) { + redisServerAddress = val } func (r *Redis) UseTLS() bool { - return true + return useTLS } func (r *Redis) GetServerAddress() string { - return "http://mock-server-address:8080" + return redisServerAddress } diff --git a/tests/mock/reposerver.go b/tests/mock/reposerver.go index d6c05ce39..1abe7826f 100644 --- a/tests/mock/reposerver.go +++ b/tests/mock/reposerver.go @@ -13,6 +13,14 @@ type Reposerver struct { Namespace string } +var ( + reposerveraddress = "" +) + +func (r *Reposerver) SetServerAddress(val string) { + reposerveraddress = val +} + func NewRepoServer(name, namespace string, client client.Client) *Reposerver { return &Reposerver{ Client: client, @@ -27,5 +35,5 @@ func (r *Reposerver) TriggerRollout(key string) error { } func (r *Reposerver) GetServerAddress() string { - return "http://mock-server-address:8080" + return reposerveraddress } From 6b5f94ff8b6faa32a03c9fa17c700037aad0fcaf Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Mon, 29 Jan 2024 09:33:29 -0500 Subject: [PATCH 88/94] add unit test for get args Signed-off-by: Jaideep Rao --- controllers/argocd/argocd_controller.go | 2 +- controllers/argocd/reposerver/helper.go | 18 ++--- controllers/argocd/reposerver/helper_test.go | 64 +++++++++++++++++ controllers/argocd/reposerver/reposerver.go | 2 +- .../argocd/reposerver/reposerver_test.go | 70 +++++++++++++++++++ controllers/argocd/reposerver/secret_test.go | 7 ++ 6 files changed, 152 insertions(+), 11 deletions(-) diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 4d629de1e..16f93d860 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -393,7 +393,7 @@ func (r *ArgoCDReconciler) reconcileControllers() error { return err } - if r.Instance.Spec.Repo.Enabled != nil && *r.Instance.Spec.Repo.Enabled { + if r.Instance.Spec.Repo.IsEnabled() { if err := r.ReposerverController.Reconcile(); err != nil { r.Logger.Error(err, "failed to reconcile repo-server controller") return err diff --git a/controllers/argocd/reposerver/helper.go b/controllers/argocd/reposerver/helper.go index 29158cbbc..581f34319 100644 --- a/controllers/argocd/reposerver/helper.go +++ b/controllers/argocd/reposerver/helper.go @@ -66,17 +66,17 @@ func (rsr *RepoServerReconciler) getArgs() []string { if rsr.Instance.Spec.Redis.IsEnabled() { cmd = append(cmd, common.RedisCmd, rsr.Redis.GetServerAddress()) - } else { - rsr.Logger.Info("redis is disabled, skipping redis configuration") - } - if rsr.Redis.UseTLS() { - cmd = append(cmd, common.RedisUseTLSCmd) - if rsr.Instance.Spec.Redis.DisableTLSVerification { - cmd = append(cmd, common.RedisInsecureSkipTLSVerifyCmd) - } else { - cmd = append(cmd, common.RedisCACertificate, redisTLSCertPath) + if rsr.Redis.UseTLS() { + cmd = append(cmd, common.RedisUseTLSCmd) + if rsr.Instance.Spec.Redis.DisableTLSVerification { + cmd = append(cmd, common.RedisInsecureSkipTLSVerifyCmd) + } else { + cmd = append(cmd, common.RedisCACertificate, redisTLSCertPath) + } } + } else { + rsr.Logger.Debug("redis is disabled; skipping redis configuration") } cmd = append(cmd, common.LogLevelCmd) diff --git a/controllers/argocd/reposerver/helper_test.go b/controllers/argocd/reposerver/helper_test.go index 00c3e366b..c1c308aef 100644 --- a/controllers/argocd/reposerver/helper_test.go +++ b/controllers/argocd/reposerver/helper_test.go @@ -6,6 +6,7 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/util" + "github.com/argoproj-labs/argocd-operator/tests/mock" "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" @@ -253,3 +254,66 @@ func TestGetReplicas(t *testing.T) { }) } } + +func TestGetArgs(t *testing.T) { + + tests := []struct { + name string + reconciler *RepoServerReconciler + useTLS bool + expectedCmd []string + }{ + { + name: "redis disabled", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Redis.Enabled = util.BoolPtr(false) + }, + ), + ), + useTLS: false, + expectedCmd: []string{"uid_entrypoint.sh", "argocd-repo-server", "--loglevel", "info", "--logformat", "text"}, + }, + { + name: "redis enabled, UseTLS true, disable TLS verification true", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Redis.Enabled = util.BoolPtr(true) + cr.Spec.Redis.DisableTLSVerification = true + }, + ), + ), + useTLS: true, + expectedCmd: []string{"uid_entrypoint.sh", "argocd-repo-server", "--redis", "http://mock-redis-server", "--redis-use-tls", "--redis-insecure-skip-tls-verify", "--loglevel", "info", "--logformat", "text"}, + }, + { + name: "redis enabled, UseTLS true, disable TLS verification false", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD( + func(cr *argoproj.ArgoCD) { + cr.Spec.Redis.Enabled = util.BoolPtr(true) + cr.Spec.Redis.DisableTLSVerification = false + }, + ), + ), + useTLS: true, + expectedCmd: []string{"uid_entrypoint.sh", "argocd-repo-server", "--redis", "http://mock-redis-server", "--redis-use-tls", "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt", "--loglevel", "info", "--logformat", "text"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockRedisName := "test-argocd-redis" + mockRedis := mock.NewRedis(mockRedisName, test.TestNamespace, tt.reconciler.Client) + mockRedis.SetUseTLS(tt.useTLS) + mockRedis.SetServerAddress("http://mock-redis-server") + tt.reconciler.Redis = mockRedis + gotArgs := tt.reconciler.getArgs() + + assert.Equal(t, tt.expectedCmd, gotArgs) + + }) + } +} diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index ca3922f92..883de50e2 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -46,7 +46,7 @@ func (rsr *RepoServerReconciler) Reconcile() error { return err } } else { - if err := rsr.deleteServiceMonitor(resourceName, rsr.Instance.Namespace); err != nil { + if err := rsr.deleteServiceMonitor(resourceMetricsName, rsr.Instance.Namespace); err != nil { rsr.Logger.Error(err, "DeleteResources: failed to delete serviceMonitor") return err } diff --git a/controllers/argocd/reposerver/reposerver_test.go b/controllers/argocd/reposerver/reposerver_test.go index 62aa5c48c..09d5be2af 100644 --- a/controllers/argocd/reposerver/reposerver_test.go +++ b/controllers/argocd/reposerver/reposerver_test.go @@ -9,6 +9,7 @@ import ( "github.com/argoproj-labs/argocd-operator/pkg/resource" "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/argoproj-labs/argocd-operator/tests/mock" "github.com/argoproj-labs/argocd-operator/tests/test" monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" @@ -36,6 +37,75 @@ func makeTestReposerverReconciler(cr *argoproj.ArgoCD, objs ...client.Object) *R } } +func TestReconcile(t *testing.T) { + mockServerName := "test-argocd-server" + mockAppControllerName := "test-argocd-app-controller" + mockRedisName := "test-argocd-redis" + + testArgoCD := test.MakeTestArgoCD() + reconciler := makeTestReposerverReconciler( + testArgoCD, + ) + + mockRedis := mock.NewRedis(mockRedisName, test.TestNamespace, reconciler.Client) + mockRedis.SetUseTLS(true) + mockRedis.SetServerAddress("http://mock-redis-server") + + reconciler.varSetter() + reconciler.Server = mock.NewServer(mockServerName, test.TestNamespace, reconciler.Client) + reconciler.Appcontroller = mock.NewAppController(mockAppControllerName, test.TestNamespace, reconciler.Client) + reconciler.Redis = mockRedis + + expectedResources := []client.Object{ + test.MakeTestServiceAccount( + func(sa *corev1.ServiceAccount) { + sa.Name = resourceName + }, + ), + test.MakeTestService( + func(s *corev1.Service) { + s.Name = resourceName + }, + ), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = resourceName + }, + ), + } + + err := reconciler.Reconcile() + assert.NoError(t, err) + + for _, obj := range expectedResources { + _, err := resource.GetObject(resourceName, test.TestNamespace, obj, reconciler.Client) + assert.NoError(t, err) + } + + monitoring.SetPrometheusAPIFound(true) + defer monitoring.SetPrometheusAPIFound(false) + + testArgoCD.Spec.Prometheus.Enabled = true + reconciler.Instance = testArgoCD + + err = reconciler.Reconcile() + assert.NoError(t, err) + + sm, err := resource.GetObject(resourceMetricsName, test.TestNamespace, test.MakeTestServiceMonitor(), reconciler.Client) + assert.NoError(t, err) + assert.NotNil(t, sm) + + testArgoCD.Spec.Prometheus.Enabled = false + reconciler.Instance = testArgoCD + + err = reconciler.Reconcile() + assert.NoError(t, err) + + _, err = resource.GetObject(resourceMetricsName, test.TestNamespace, test.MakeTestServiceMonitor(), reconciler.Client) + assert.True(t, apierrors.IsNotFound(err)) + +} + func TestDeleteResources(t *testing.T) { tests := []struct { name string diff --git a/controllers/argocd/reposerver/secret_test.go b/controllers/argocd/reposerver/secret_test.go index 80fc9d490..9a3180c16 100644 --- a/controllers/argocd/reposerver/secret_test.go +++ b/controllers/argocd/reposerver/secret_test.go @@ -3,6 +3,8 @@ package reposerver import ( "testing" + argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" + "github.com/argoproj-labs/argocd-operator/pkg/resource" "github.com/argoproj-labs/argocd-operator/pkg/workloads" "github.com/argoproj-labs/argocd-operator/tests/mock" "github.com/argoproj-labs/argocd-operator/tests/test" @@ -121,6 +123,11 @@ func TestReconcileTLSSecret(t *testing.T) { assert.NoError(t, err, "Expected no error but got one.") } + res, err := resource.GetObject(test.TestArgoCDName, test.TestNamespace, &argoproj.ArgoCD{}, reconciler.Client) + assert.NoError(t, err) + argocd := res.(*argoproj.ArgoCD) + assert.NotEqual(t, "", argocd.Status.RepoTLSChecksum) + dep, err := workloads.GetDeployment(mockServerName, test.TestNamespace, reconciler.Client) assert.NoError(t, err) _, ok := dep.Spec.Template.ObjectMeta.Labels["repo.tls.cert.changed"] From 0deea8363b536c754868610b6f481aa559cefd5c Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Tue, 30 Jan 2024 16:36:17 -0500 Subject: [PATCH 89/94] wip add deployment unit test Signed-off-by: Jaideep Rao --- controllers/argocd/reposerver/deployment.go | 71 ++-- .../argocd/reposerver/deployment_test.go | 320 ++++++++++++++++++ 2 files changed, 356 insertions(+), 35 deletions(-) diff --git a/controllers/argocd/reposerver/deployment.go b/controllers/argocd/reposerver/deployment.go index 9c8e7b15f..c6c4e8ec2 100644 --- a/controllers/argocd/reposerver/deployment.go +++ b/controllers/argocd/reposerver/deployment.go @@ -185,10 +185,46 @@ func (rsr *RepoServerReconciler) getContainers() []corev1.Container { repoServerEnv = util.EnvMerge(repoServerEnv, []corev1.EnvVar{{Name: common.ArgoCDExecTimeoutEnvVar, Value: fmt.Sprintf("%ds", *rsr.Instance.Spec.Repo.ExecTimeout)}}, true) } + volumeMounts := []corev1.VolumeMount{ + { + Name: common.SSHKnownHosts, + MountPath: common.VolumeMountPathSSH, + }, + { + Name: common.TLSCerts, + MountPath: common.VolumeMountPathTLS, + }, + { + Name: common.GPGKeys, + MountPath: common.VolumeMountPathGPG, + }, + { + Name: common.GPGKeyRing, + MountPath: common.VolumeMountPathGPGKeyring, + }, + { + Name: common.VolumeTmp, + MountPath: common.VolumeMountPathTmp, + }, + { + Name: common.ArgoCDRepoServerTLSSecretName, + MountPath: common.VolumeMountPathRepoServerTLS, + }, + { + Name: common.ArgoCDRedisServerTLSSecretName, + MountPath: redisTLSPath, + }, + { + Name: "plugins", + MountPath: cmpServerPluginsPath, + }, + } + containers := []corev1.Container{{ Command: rsr.getArgs(), Image: argocdcommon.GetArgoContainerImage(rsr.Instance), ImagePullPolicy: corev1.PullAlways, + VolumeMounts: volumeMounts, Name: common.ArgoCDRepoServerName, Env: repoServerEnv, Resources: rsr.getResources(), @@ -230,41 +266,6 @@ func (rsr *RepoServerReconciler) getContainers() []corev1.Container { }, }} - volumeMounts := []corev1.VolumeMount{ - { - Name: common.SSHKnownHosts, - MountPath: common.VolumeMountPathSSH, - }, - { - Name: common.TLSCerts, - MountPath: common.VolumeMountPathTLS, - }, - { - Name: common.GPGKeys, - MountPath: common.VolumeMountPathGPG, - }, - { - Name: common.GPGKeyRing, - MountPath: common.VolumeMountPathGPGKeyring, - }, - { - Name: common.VolumeTmp, - MountPath: common.VolumeMountPathTmp, - }, - { - Name: common.ArgoCDRepoServerTLSSecretName, - MountPath: common.VolumeMountPathRepoServerTLS, - }, - { - Name: common.ArgoCDRedisServerTLSSecretName, - MountPath: redisTLSPath, - }, - { - Name: "plugins", - MountPath: cmpServerPluginsPath, - }, - } - if rsr.Instance.Spec.Repo.VolumeMounts != nil { containers[0].VolumeMounts = append(volumeMounts, rsr.Instance.Spec.Repo.VolumeMounts...) } diff --git a/controllers/argocd/reposerver/deployment_test.go b/controllers/argocd/reposerver/deployment_test.go index 773e854ec..52b7945c0 100644 --- a/controllers/argocd/reposerver/deployment_test.go +++ b/controllers/argocd/reposerver/deployment_test.go @@ -3,12 +3,114 @@ package reposerver import ( "testing" + "github.com/argoproj-labs/argocd-operator/controllers/argocd/argocdcommon" + "github.com/argoproj-labs/argocd-operator/pkg/util" "github.com/argoproj-labs/argocd-operator/pkg/workloads" + "github.com/argoproj-labs/argocd-operator/tests/mock" "github.com/argoproj-labs/argocd-operator/tests/test" "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) +func TestReconcileDeployment(t *testing.T) { + mockRedisName := "test-argocd-redis" + + tests := []struct { + name string + reconciler *RepoServerReconciler + expectedError bool + expectedDeployment *appsv1.Deployment + }{ + { + name: "Deployment does not exist", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + ), + expectedError: false, + expectedDeployment: getDesiredDeployment(), + }, + { + name: "Deployment exists", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = "test-argocd-repo-server" + }, + ), + ), + expectedError: false, + expectedDeployment: getDesiredDeployment(), + }, + { + name: "Deployment drift", + reconciler: makeTestReposerverReconciler( + test.MakeTestArgoCD(), + test.MakeTestDeployment( + func(d *appsv1.Deployment) { + d.Name = "test-argocd-repo-server" + // Modify some fields to simulate drift + d.Spec.Template.Spec.Containers = []corev1.Container{ + { + Name: "argocd-repo-server", + Image: "random-img", + }, + } + }, + ), + ), + expectedError: false, + expectedDeployment: getDesiredDeployment(), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.reconciler.varSetter() + + mockRedis := mock.NewRedis(mockRedisName, test.TestNamespace, tt.reconciler.Client) + mockRedis.SetServerAddress("http://mock-server-address") + mockRedis.SetUseTLS(true) + tt.reconciler.Redis = mockRedis + + err := tt.reconciler.reconcileDeployment() + assert.NoError(t, err) + + existing, err := workloads.GetDeployment("test-argocd-repo-server", test.TestNamespace, tt.reconciler.Client) + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none.") + } else { + assert.NoError(t, err, "Expected no error but got one.") + } + + if tt.expectedDeployment != nil { + match := true + + ftc := []argocdcommon.FieldToCompare{ + {Existing: &existing.Spec.Template.Spec.NodeSelector, Desired: &tt.expectedDeployment.Spec.Template.Spec.NodeSelector}, + {Existing: &existing.Spec.Template.Spec.Volumes, Desired: &tt.expectedDeployment.Spec.Template.Spec.Volumes}, + // {Existing: &existing.Spec.Template.Spec.Containers[0], Desired: &tt.expectedDeployment.Spec.Template.Spec.Containers[0]}, + {Existing: &existing.Spec.Template.Spec.InitContainers, Desired: &tt.expectedDeployment.Spec.Template.Spec.InitContainers}, + {Existing: &existing.Spec.Template.Spec.ServiceAccountName, Desired: &tt.expectedDeployment.Spec.Template.Spec.ServiceAccountName}, + {Existing: &existing.Spec.Template.Spec.SecurityContext, Desired: &tt.expectedDeployment.Spec.Template.Spec.SecurityContext}, + {Existing: &existing.Spec.Replicas, Desired: &tt.expectedDeployment.Spec.Replicas}, + {Existing: &existing.Spec.Selector, Desired: &tt.expectedDeployment.Spec.Selector}, + {Existing: &existing.Labels, Desired: &tt.expectedDeployment.Labels}, + {Existing: &existing.Annotations, Desired: &tt.expectedDeployment.Annotations}, + } + argocdcommon.PartialMatch(ftc, &match) + assert.True(t, match) + } + + }) + } +} + func TestDeleteDeployment(t *testing.T) { tests := []struct { name string @@ -53,3 +155,221 @@ func TestDeleteDeployment(t *testing.T) { }) } } + +func getDesiredDeployment() *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-argocd-repo-server", + Namespace: "test-ns", + Labels: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server", + "app.kubernetes.io/part-of": "argocd", + "app.kubernetes.io/instance": "test-argocd", + "app.kubernetes.io/managed-by": "argocd-operator", + "app.kubernetes.io/component": "repo-server", + }, + Annotations: map[string]string{ + "argocds.argoproj.io/name": "test-argocd", + "argocds.argoproj.io/namespace": "test-ns", + }, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/name": "test-argocd-repo-server", + }, + }, + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "ssh-known-hosts", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "argocd-ssh-known-hosts-cm", + }, + }, + }, + }, + { + Name: "tls-certs", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "argocd-tls-certs-cm", + }, + }, + }, + }, + { + Name: "gpg-keys", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "argocd-gpg-keys-cm", + }, + }, + }, + }, + { + Name: "gpg-keyring", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "tmp", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "argocd-repo-server-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "argocd-repo-server-tls", + Optional: util.BoolPtr(true), + }, + }, + }, + { + Name: "argocd-operator-redis-tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "argocd-operator-redis-tls", + Optional: util.BoolPtr(true), + }, + }, + }, + { + Name: "var-files", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "plugins", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }, + InitContainers: []corev1.Container{ + { + Name: "copyutil", + Image: "quay.io/argoproj/argocd@sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc", + Command: []string{"cp", "-n", "/usr/local/bin/argocd", "/var/run/argocd/argocd-cmp-server"}, + ImagePullPolicy: "Always", + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: util.BoolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: util.BoolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "var-files", + MountPath: "var/run/argocd", + }, + }, + }, + }, + Containers: []corev1.Container{ + { + Name: "argocd-repo-server", + Image: "quay.io/argoproj/argocd@sha256:8576d347f30fa4c56a0129d1c0a0f5ed1e75662f0499f1ed7e917c405fd909dc", + Command: []string{"uid_entrypoint.sh", "argocd-repo-server", "--redis", "http://mock-redis-server", "--redis-use-tls", "--redis-ca-certificate", "/app/config/reposerver/tls/redis/tls.crt", "--loglevel", "info", "--logformat", "text"}, + ImagePullPolicy: "Always", + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(8081), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + TCPSocket: &corev1.TCPSocketAction{ + Port: intstr.FromInt(8081), + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 10, + }, + Ports: []corev1.ContainerPort{ + { + ContainerPort: 8081, + Name: "server", + }, { + ContainerPort: 8084, + Name: "metrics", + }, + }, + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: util.BoolPtr(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{ + "ALL", + }, + }, + RunAsNonRoot: util.BoolPtr(true), + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "ssh-known-hosts", + MountPath: "/app/config/ssh", + }, + { + Name: "tls-certs", + MountPath: "/app/config/tls", + }, + { + Name: "gpg-keys", + MountPath: "/app/config/gpg/source", + }, + { + Name: "gpg-keyring", + MountPath: "/app/config/gpg/keys", + }, + { + Name: "tmp", + MountPath: "/tmp", + }, + { + Name: "argocd-repo-server-tls", + MountPath: "/app/config/reposerver/tls", + }, + { + Name: "argocd-operator-redis-tls", + MountPath: "/app/config/reposerver/tls/redis", + }, + { + Name: "plugins", + MountPath: "/home/argocd/cmp-server/plugins", + }, + }, + }, + }, + SecurityContext: &corev1.PodSecurityContext{ + RunAsNonRoot: util.BoolPtr(true), + }, + NodeSelector: map[string]string{ + "kubernetes.io/os": "linux", + }, + ServiceAccountName: "test-argocd-repo-server", + }, + }, + }, + } +} From e68a4782e9f688273e20da9a57e251c17656747c Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Tue, 30 Jan 2024 16:46:12 -0500 Subject: [PATCH 90/94] add metrics suffix, generalize name generation logic Signed-off-by: Jaideep Rao --- common/names.go | 2 ++ pkg/argoutil/resource.go | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/common/names.go b/common/names.go index 8c619ead7..ca662016e 100644 --- a/common/names.go +++ b/common/names.go @@ -34,4 +34,6 @@ const ( const ( // ArgoCDCASuffix is the name suffix for ArgoCD CA resources. ArgoCDCASuffix = "ca" + + MetricsSuffix = "metrics" ) diff --git a/pkg/argoutil/resource.go b/pkg/argoutil/resource.go index 94f3dc91d..ae112cef0 100644 --- a/pkg/argoutil/resource.go +++ b/pkg/argoutil/resource.go @@ -16,6 +16,7 @@ package argoutil import ( "fmt" + "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -29,9 +30,9 @@ func FqdnServiceRef(serviceName, namespace string, port int) string { return fmt.Sprintf("%s.%s.svc.cluster.local:%d", serviceName, namespace, port) } -// NameWithSuffix will return a string using the Name from the given ObjectMeta with the provded suffix appended. -func NameWithSuffix(name, suffix string) string { - return fmt.Sprintf("%s-%s", name, suffix) +// NameWithSuffix will return a string using the Name from the given ObjectMeta with the provded suffixes appended. +func NameWithSuffix(name string, suffixes ...string) string { + return fmt.Sprintf("%s-%s", name, strings.Join(suffixes, "-")) } // GenerateResourceName generates names for namespace scoped resources @@ -40,8 +41,8 @@ func GenerateResourceName(instanceName, suffix string) string { } // GenerateUniqueResourceName generates unique names for cluster scoped resources -func GenerateUniqueResourceName(instanceName, instanceNamespace, suffix string) string { - return fmt.Sprintf("%s-%s-%s", instanceName, instanceNamespace, suffix) +func GenerateUniqueResourceName(instanceName, instanceNamespace string, suffixes ...string) string { + return NameWithSuffix(NameWithSuffix(instanceName, instanceName), suffixes...) } func GetObjMeta(resName, resNs, instanceName, instanceNs, component string) metav1.ObjectMeta { From ba9f1f6c3721f443d0c6d6b274d78336ebde2d14 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Tue, 30 Jan 2024 16:49:55 -0500 Subject: [PATCH 91/94] fix method signature Signed-off-by: Jaideep Rao --- pkg/argoutil/resource.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/argoutil/resource.go b/pkg/argoutil/resource.go index ae112cef0..ce7605685 100644 --- a/pkg/argoutil/resource.go +++ b/pkg/argoutil/resource.go @@ -36,8 +36,8 @@ func NameWithSuffix(name string, suffixes ...string) string { } // GenerateResourceName generates names for namespace scoped resources -func GenerateResourceName(instanceName, suffix string) string { - return NameWithSuffix(instanceName, suffix) +func GenerateResourceName(instanceName string, suffixes ...string) string { + return NameWithSuffix(instanceName, suffixes...) } // GenerateUniqueResourceName generates unique names for cluster scoped resources From 9d9024184c1ad9a07cb3634e41c8d2e05f08b494 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Tue, 30 Jan 2024 16:53:12 -0500 Subject: [PATCH 92/94] remove need for dedicated metrics suffix Signed-off-by: Jaideep Rao --- common/reposerver.go | 2 -- controllers/argocd/reposerver/reposerver.go | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/common/reposerver.go b/common/reposerver.go index 75e9027e0..6dcce63b1 100644 --- a/common/reposerver.go +++ b/common/reposerver.go @@ -16,8 +16,6 @@ const ( // suffixes const ( RepoServerSuffix = "repo-server" - - RepoServerMetricsSuffix = "repo-server-metrics" ) // values diff --git a/controllers/argocd/reposerver/reposerver.go b/controllers/argocd/reposerver/reposerver.go index 883de50e2..a462e6aa3 100644 --- a/controllers/argocd/reposerver/reposerver.go +++ b/controllers/argocd/reposerver/reposerver.go @@ -123,5 +123,5 @@ func (rsr *RepoServerReconciler) TriggerRollout(key string) error { func (rsr *RepoServerReconciler) varSetter() { component = common.RepoServerComponent resourceName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerSuffix) - resourceMetricsName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerMetricsSuffix) + resourceMetricsName = argoutil.GenerateResourceName(rsr.Instance.Name, common.RepoServerSuffix, common.MetricsSuffix) } From 4c8bb5f02eefd1015cf58875e0f495fcaab57096 Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Wed, 31 Jan 2024 17:46:22 -0500 Subject: [PATCH 93/94] allow passing in existing resources to test fns for minor drift checks Signed-off-by: Jaideep Rao --- .../applicationset/applicationset_test.go | 2 +- .../argocd/applicationset/deployment_test.go | 4 +- .../argocd/applicationset/role_test.go | 4 +- .../argocd/applicationset/rolebinding_test.go | 4 +- .../argocd/applicationset/service_test.go | 4 +- .../applicationset/serviceaccount_test.go | 4 +- .../applicationset/webhookroute_test.go | 6 +- .../argocd/notifications/configmap_test.go | 4 +- .../argocd/notifications/deployment_test.go | 4 +- .../notifications/notifications_test.go | 4 +- controllers/argocd/notifications/role_test.go | 4 +- .../argocd/notifications/rolebinding_test.go | 4 +- .../argocd/notifications/secret_test.go | 4 +- .../notifications/serviceaccount_test.go | 4 +- pkg/cluster/namespace_test.go | 24 +- pkg/monitoring/prometheusRule_test.go | 22 +- pkg/monitoring/serviceMonitor_test.go | 24 +- pkg/networking/service_test.go | 24 +- pkg/permissions/clusterrole_test.go | 24 +- pkg/permissions/clusterrolebinding_test.go | 20 +- pkg/permissions/role_test.go | 24 +- pkg/permissions/rolebinding_test.go | 22 +- pkg/workloads/configmap_test.go | 24 +- pkg/workloads/deployment_test.go | 24 +- pkg/workloads/hpa_test.go | 24 +- pkg/workloads/secret_test.go | 24 +- pkg/workloads/statefulset_test.go | 24 +- tests/test/testing.go | 299 ++++++++++-------- 28 files changed, 344 insertions(+), 315 deletions(-) diff --git a/controllers/argocd/applicationset/applicationset_test.go b/controllers/argocd/applicationset/applicationset_test.go index 50ef5f472..9d303d03a 100644 --- a/controllers/argocd/applicationset/applicationset_test.go +++ b/controllers/argocd/applicationset/applicationset_test.go @@ -29,7 +29,7 @@ func makeTestApplicationSetReconciler(t *testing.T, webhookServerRouteEnabled bo return &ApplicationSetReconciler{ Client: cl, Scheme: s, - Instance: test.MakeTestArgoCD(func(a *argoproj.ArgoCD) { + Instance: test.MakeTestArgoCD(nil, func(a *argoproj.ArgoCD) { a.Spec.ApplicationSet = &argoproj.ArgoCDApplicationSet{ WebhookServer: argoproj.WebhookServerSpec{ Route: argoproj.ArgoCDRouteSpec{ diff --git a/controllers/argocd/applicationset/deployment_test.go b/controllers/argocd/applicationset/deployment_test.go index edfad7536..288a736fe 100644 --- a/controllers/argocd/applicationset/deployment_test.go +++ b/controllers/argocd/applicationset/deployment_test.go @@ -14,7 +14,7 @@ import ( func TestApplicationSetReconciler_reconcileDeployment(t *testing.T) { resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) asr := makeTestApplicationSetReconciler(t, false, ns) existingDeployment := asr.getDesiredDeployment() @@ -64,7 +64,7 @@ func TestApplicationSetReconciler_reconcileDeployment(t *testing.T) { } func TestApplicationSetReconciler_DeleteDeployment(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/controllers/argocd/applicationset/role_test.go b/controllers/argocd/applicationset/role_test.go index e52dca8c3..122f6f507 100644 --- a/controllers/argocd/applicationset/role_test.go +++ b/controllers/argocd/applicationset/role_test.go @@ -14,7 +14,7 @@ import ( ) func TestApplicationSetReconciler_reconcileRole(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName existingRole := &rbacv1.Role{ TypeMeta: metav1.TypeMeta{ @@ -73,7 +73,7 @@ func TestApplicationSetReconciler_reconcileRole(t *testing.T) { } func TestApplicationSetReconciler_DeleteRole(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/controllers/argocd/applicationset/rolebinding_test.go b/controllers/argocd/applicationset/rolebinding_test.go index 240670ec3..cdaa16768 100644 --- a/controllers/argocd/applicationset/rolebinding_test.go +++ b/controllers/argocd/applicationset/rolebinding_test.go @@ -16,7 +16,7 @@ import ( func TestApplicationSetReconciler_reconcileRoleBinding(t *testing.T) { resourceName = test.TestArgoCDName - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) sa := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { sa.Name = resourceName }) @@ -76,7 +76,7 @@ func TestApplicationSetReconciler_reconcileRoleBinding(t *testing.T) { } func TestApplicationSetReconciler_DeleteRoleBinding(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) sa := test.MakeTestServiceAccount() resourceName = test.TestArgoCDName tests := []struct { diff --git a/controllers/argocd/applicationset/service_test.go b/controllers/argocd/applicationset/service_test.go index 815ceec08..03782e9ed 100644 --- a/controllers/argocd/applicationset/service_test.go +++ b/controllers/argocd/applicationset/service_test.go @@ -11,7 +11,7 @@ import ( ) func TestApplicationSetReconciler_reconcileService(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) sa := test.MakeTestServiceAccount() resourceName = test.TestArgoCDName @@ -50,7 +50,7 @@ func TestApplicationSetReconciler_reconcileService(t *testing.T) { } func TestApplicationSetReconciler_DeleteService(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) sa := test.MakeTestServiceAccount() resourceName = test.TestArgoCDName tests := []struct { diff --git a/controllers/argocd/applicationset/serviceaccount_test.go b/controllers/argocd/applicationset/serviceaccount_test.go index 769ea2d52..010964a4f 100644 --- a/controllers/argocd/applicationset/serviceaccount_test.go +++ b/controllers/argocd/applicationset/serviceaccount_test.go @@ -11,7 +11,7 @@ import ( ) func TestApplicationSetReconciler_reconcileServiceAccount(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels @@ -51,7 +51,7 @@ func TestApplicationSetReconciler_reconcileServiceAccount(t *testing.T) { } func TestApplicationSetReconciler_DeleteServiceAccount(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/controllers/argocd/applicationset/webhookroute_test.go b/controllers/argocd/applicationset/webhookroute_test.go index d538df387..54cd4329d 100644 --- a/controllers/argocd/applicationset/webhookroute_test.go +++ b/controllers/argocd/applicationset/webhookroute_test.go @@ -14,7 +14,7 @@ import ( func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { resourceLabels = testExpectedLabels - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) asr := makeTestApplicationSetReconciler(t, true, ns) existingWebhookRoute := asr.getDesiredWebhookRoute() @@ -67,7 +67,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute(t *testing.T) { } func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabled(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) tests := []struct { name string @@ -106,7 +106,7 @@ func TestApplicationSetReconciler_reconcileWebhookRoute_WebhookServerRouteDisabl } func TestApplicationSetReconciler_deleteWebhookRoute(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) tests := []struct { name string webhookServerRouteEnabled bool diff --git a/controllers/argocd/notifications/configmap_test.go b/controllers/argocd/notifications/configmap_test.go index 645f71e40..074a8042a 100644 --- a/controllers/argocd/notifications/configmap_test.go +++ b/controllers/argocd/notifications/configmap_test.go @@ -14,7 +14,7 @@ import ( ) func TestNotificationsReconciler_reconcileConfigMap(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) tests := []struct { name string @@ -52,7 +52,7 @@ func TestNotificationsReconciler_reconcileConfigMap(t *testing.T) { } func TestNotificationsReconciler_DeleteConfigMap(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/deployment_test.go b/controllers/argocd/notifications/deployment_test.go index 25400f0a6..3ccc4b9da 100644 --- a/controllers/argocd/notifications/deployment_test.go +++ b/controllers/argocd/notifications/deployment_test.go @@ -15,7 +15,7 @@ import ( func TestNotificationsReconciler_reconcileDeployment(t *testing.T) { resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) nr := makeTestNotificationsReconciler(t, ns) existingDeployment := nr.getDesiredDeployment() @@ -65,7 +65,7 @@ func TestNotificationsReconciler_reconcileDeployment(t *testing.T) { } func TestNotificationsReconciler_DeleteDeployment(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/controllers/argocd/notifications/notifications_test.go b/controllers/argocd/notifications/notifications_test.go index 8f5e961f1..80f66ceab 100644 --- a/controllers/argocd/notifications/notifications_test.go +++ b/controllers/argocd/notifications/notifications_test.go @@ -26,13 +26,13 @@ func makeTestNotificationsReconciler(t *testing.T, objs ...runtime.Object) *Noti return &NotificationsReconciler{ Client: cl, Scheme: s, - Instance: test.MakeTestArgoCD(), + Instance: test.MakeTestArgoCD(nil), Logger: logger, } } func TestNotificationsReconciler_Reconcile(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/controllers/argocd/notifications/role_test.go b/controllers/argocd/notifications/role_test.go index 82cda1137..23fe463ba 100644 --- a/controllers/argocd/notifications/role_test.go +++ b/controllers/argocd/notifications/role_test.go @@ -14,7 +14,7 @@ import ( ) func TestNotificationsReconciler_reconcileRole(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName existingRole := &rbacv1.Role{ TypeMeta: metav1.TypeMeta{ @@ -73,7 +73,7 @@ func TestNotificationsReconciler_reconcileRole(t *testing.T) { } func TestNotificationsReconciler_DeleteRole(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/controllers/argocd/notifications/rolebinding_test.go b/controllers/argocd/notifications/rolebinding_test.go index c29014268..a94e9bebb 100644 --- a/controllers/argocd/notifications/rolebinding_test.go +++ b/controllers/argocd/notifications/rolebinding_test.go @@ -16,7 +16,7 @@ import ( func TestNotificationsReconciler_reconcileRoleBinding(t *testing.T) { resourceName = test.TestArgoCDName - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) sa := test.MakeTestServiceAccount(func(sa *corev1.ServiceAccount) { sa.Name = resourceName }) @@ -76,7 +76,7 @@ func TestNotificationsReconciler_reconcileRoleBinding(t *testing.T) { } func TestNotificationsReconciler_DeleteRoleBinding(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) sa := test.MakeTestServiceAccount() resourceName = test.TestArgoCDName tests := []struct { diff --git a/controllers/argocd/notifications/secret_test.go b/controllers/argocd/notifications/secret_test.go index 9350c5d0f..1af36d961 100644 --- a/controllers/argocd/notifications/secret_test.go +++ b/controllers/argocd/notifications/secret_test.go @@ -14,7 +14,7 @@ import ( ) func TestNotificationsReconciler_reconcileSecret(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceLabels = testExpectedLabels tests := []struct { name string @@ -52,7 +52,7 @@ func TestNotificationsReconciler_reconcileSecret(t *testing.T) { } func TestNotificationsReconciler_DeleteSecret(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) tests := []struct { name string setupClient func() *NotificationsReconciler diff --git a/controllers/argocd/notifications/serviceaccount_test.go b/controllers/argocd/notifications/serviceaccount_test.go index 1daf460d1..bfb6cc9bf 100644 --- a/controllers/argocd/notifications/serviceaccount_test.go +++ b/controllers/argocd/notifications/serviceaccount_test.go @@ -11,7 +11,7 @@ import ( ) func TestNotificationsReconciler_reconcileServiceAccount(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName resourceLabels = testExpectedLabels @@ -51,7 +51,7 @@ func TestNotificationsReconciler_reconcileServiceAccount(t *testing.T) { } func TestNotificationsReconciler_DeleteServiceAccount(t *testing.T) { - ns := test.MakeTestNamespace() + ns := test.MakeTestNamespace(nil) resourceName = test.TestArgoCDName tests := []struct { name string diff --git a/pkg/cluster/namespace_test.go b/pkg/cluster/namespace_test.go index d7d85fb0a..5fb07543a 100644 --- a/pkg/cluster/namespace_test.go +++ b/pkg/cluster/namespace_test.go @@ -50,7 +50,7 @@ func TestRequestNamespace(t *testing.T) { Labels: test.TestKVP, }, }, - desiredNamespace: test.MakeTestNamespace(func(ns *corev1.Namespace) { + desiredNamespace: test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName ns.Labels = test.TestKVP }), @@ -68,7 +68,7 @@ func TestRequestNamespace(t *testing.T) { }, Client: testClient, }, - desiredNamespace: test.MakeTestNamespace(func(ns *corev1.Namespace) { + desiredNamespace: test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName ns.Labels = test.TestKVPMutated }), @@ -86,7 +86,7 @@ func TestRequestNamespace(t *testing.T) { }, Client: testClient, }, - desiredNamespace: test.MakeTestNamespace(func(ns *corev1.Namespace) { + desiredNamespace: test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName ns.Labels = test.TestKVP }), @@ -111,7 +111,7 @@ func TestRequestNamespace(t *testing.T) { func TestCreateNamespace(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredNamespace := test.MakeTestNamespace(func(ns *corev1.Namespace) { + desiredNamespace := test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName ns.TypeMeta = metav1.TypeMeta{ Kind: "Namespace", @@ -130,7 +130,7 @@ func TestCreateNamespace(t *testing.T) { } func TestGetNamespace(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestNamespace(func(ns *corev1.Namespace) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName })).Build() @@ -145,14 +145,14 @@ func TestGetNamespace(t *testing.T) { } func TestListNamespaces(t *testing.T) { - namespace1 := test.MakeTestNamespace(func(ns *corev1.Namespace) { + namespace1 := test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = "namespace-1" ns.Labels = map[string]string{ common.AppK8sKeyComponent: "new-component-1", } }) - namespace2 := test.MakeTestNamespace(func(ns *corev1.Namespace) { ns.Name = "namespace-2" }) - namespace3 := test.MakeTestNamespace(func(ns *corev1.Namespace) { + namespace2 := test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = "namespace-2" }) + namespace3 := test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = "namespace-3" ns.Labels = map[string]string{ common.AppK8sKeyComponent: "new-component-2", @@ -186,11 +186,11 @@ func TestListNamespaces(t *testing.T) { } func TestUpdateNamespace(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestNamespace(func(ns *corev1.Namespace) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName })).Build() - desiredNamespace := test.MakeTestNamespace(func(ns *corev1.Namespace) { + desiredNamespace := test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName ns.Labels = test.TestKVP }) @@ -206,7 +206,7 @@ func TestUpdateNamespace(t *testing.T) { assert.Equal(t, desiredNamespace.Labels, existingNamespace.Labels) testClient = fake.NewClientBuilder().Build() - existingNamespace = test.MakeTestNamespace(func(ns *corev1.Namespace) { + existingNamespace = test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName ns.Labels = test.TestKVP }) @@ -216,7 +216,7 @@ func TestUpdateNamespace(t *testing.T) { } func TestDeleteNamespace(t *testing.T) { - testNamespace := test.MakeTestNamespace(func(ns *corev1.Namespace) { + testNamespace := test.MakeTestNamespace(nil, func(ns *corev1.Namespace) { ns.Name = test.TestName }) diff --git a/pkg/monitoring/prometheusRule_test.go b/pkg/monitoring/prometheusRule_test.go index 49eefc715..3174bf9d0 100644 --- a/pkg/monitoring/prometheusRule_test.go +++ b/pkg/monitoring/prometheusRule_test.go @@ -46,7 +46,7 @@ func TestRequestPrometheusRule(t *testing.T) { }, }, mutation: false, - desiredPrometheusRule: test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + desiredPrometheusRule: test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Labels = test.TestKVP pr.Annotations = test.TestKVP @@ -69,7 +69,7 @@ func TestRequestPrometheusRule(t *testing.T) { Client: testClient, }, mutation: true, - desiredPrometheusRule: test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + desiredPrometheusRule: test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = test.TestNameMutated pr.Labels = test.TestKVP pr.Annotations = test.TestKVP @@ -92,7 +92,7 @@ func TestRequestPrometheusRule(t *testing.T) { Client: testClient, }, mutation: true, - desiredPrometheusRule: test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + desiredPrometheusRule: test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Labels = test.TestKVP pr.Annotations = test.TestKVP }), @@ -121,7 +121,7 @@ func TestCreatePrometheusRule(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) testClient := fake.NewClientBuilder().WithScheme(s).Build() - desiredPrometheusRule := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + desiredPrometheusRule := test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.TypeMeta = metav1.TypeMeta{ Kind: "PrometheusRule", APIVersion: "monitoring.coreos.com/v1", @@ -148,7 +148,7 @@ func TestGetPrometheusRule(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = test.TestName pr.Namespace = test.TestNamespace })).Build() @@ -164,13 +164,13 @@ func TestGetPrometheusRule(t *testing.T) { } func TestListPrometheusRules(t *testing.T) { - prometheusRule1 := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + prometheusRule1 := test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-1" pr.Namespace = test.TestNamespace pr.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - prometheusRule2 := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-2" }) - prometheusRule3 := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + prometheusRule2 := test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-2" }) + prometheusRule3 := test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = "prometheusRule-3" pr.Namespace = test.TestNamespace pr.Labels[common.AppK8sKeyComponent] = "new-component-2" @@ -210,7 +210,7 @@ func TestUpdatePrometheusRule(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) // Create the initial PrometheusRule - initialPrometheusRule := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + initialPrometheusRule := test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = test.TestName pr.Namespace = test.TestNamespace }) @@ -259,7 +259,7 @@ func TestUpdatePrometheusRule(t *testing.T) { assert.Equal(t, desiredPrometheusRule.Spec.Groups, existingPrometheusRule.Spec.Groups) testClient = fake.NewClientBuilder().WithScheme(s).Build() - existingPrometheusRule = test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + existingPrometheusRule = test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = test.TestName pr.Labels = nil }) @@ -271,7 +271,7 @@ func TestDeletePrometheusRule(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testPrometheusRule := test.MakeTestPrometheusRule(func(pr *monitoringv1.PrometheusRule) { + testPrometheusRule := test.MakeTestPrometheusRule(nil, func(pr *monitoringv1.PrometheusRule) { pr.Name = test.TestName pr.Namespace = test.TestNamespace }) diff --git a/pkg/monitoring/serviceMonitor_test.go b/pkg/monitoring/serviceMonitor_test.go index efd36b399..0267967d4 100644 --- a/pkg/monitoring/serviceMonitor_test.go +++ b/pkg/monitoring/serviceMonitor_test.go @@ -48,7 +48,7 @@ func TestRequestServiceMonitor(t *testing.T) { }, }, }, - desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + desiredServiceMonitor: test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Labels = test.TestKVP sm.Annotations = test.TestKVP }), @@ -69,7 +69,7 @@ func TestRequestServiceMonitor(t *testing.T) { }, }, }, - desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + desiredServiceMonitor: test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Labels = test.TestKVP sm.Annotations = test.TestKVP }), @@ -94,7 +94,7 @@ func TestRequestServiceMonitor(t *testing.T) { }, Client: testClient, }, - desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + desiredServiceMonitor: test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = test.TestNameMutated sm.Labels = test.TestKVP sm.Annotations = test.TestKVP @@ -120,7 +120,7 @@ func TestRequestServiceMonitor(t *testing.T) { }, Client: testClient, }, - desiredServiceMonitor: test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) {}), + desiredServiceMonitor: test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) {}), wantErr: true, }, } @@ -146,7 +146,7 @@ func TestCreateServiceMonitor(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) testClient := fake.NewClientBuilder().WithScheme(s).Build() - desiredServiceMonitor := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + desiredServiceMonitor := test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.TypeMeta = metav1.TypeMeta{ Kind: "ServiceMonitor", APIVersion: "monitoring.coreos.com/v1", @@ -173,7 +173,7 @@ func TestGetServiceMonitor(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + testClient := fake.NewClientBuilder().WithScheme(s).WithObjects(test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = test.TestName sm.Namespace = test.TestNamespace })).Build() @@ -189,13 +189,13 @@ func TestGetServiceMonitor(t *testing.T) { } func TestListServiceMonitors(t *testing.T) { - serviceMonitor1 := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + serviceMonitor1 := test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-1" sm.Namespace = test.TestNamespace sm.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - serviceMonitor2 := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-2" }) - serviceMonitor3 := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + serviceMonitor2 := test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-2" }) + serviceMonitor3 := test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = "serviceMonitor-3" sm.Namespace = test.TestNamespace sm.Labels[common.AppK8sKeyComponent] = "new-component-2" @@ -235,7 +235,7 @@ func TestUpdateServiceMonitor(t *testing.T) { assert.NoError(t, monitoringv1.AddToScheme(s)) // Create the initial ServiceMonitor - initialServiceMonitor := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + initialServiceMonitor := test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = test.TestName sm.Namespace = test.TestNamespace }) @@ -267,7 +267,7 @@ func TestUpdateServiceMonitor(t *testing.T) { assert.Equal(t, desiredServiceMonitor.Spec.Endpoints, existingServiceMonitor.Spec.Endpoints) testClient = fake.NewClientBuilder().WithScheme(s).Build() - existingServiceMonitor = test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + existingServiceMonitor = test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = test.TestName sm.Labels = nil }) @@ -279,7 +279,7 @@ func TestDeleteServiceMonitor(t *testing.T) { s := scheme.Scheme assert.NoError(t, monitoringv1.AddToScheme(s)) - testServiceMonitor := test.MakeTestServiceMonitor(func(sm *monitoringv1.ServiceMonitor) { + testServiceMonitor := test.MakeTestServiceMonitor(nil, func(sm *monitoringv1.ServiceMonitor) { sm.Name = test.TestName sm.Namespace = test.TestNamespace }) diff --git a/pkg/networking/service_test.go b/pkg/networking/service_test.go index 31d2edda1..ad6414e58 100644 --- a/pkg/networking/service_test.go +++ b/pkg/networking/service_test.go @@ -42,7 +42,7 @@ func TestRequestService(t *testing.T) { }, }, mutation: false, - desiredService: test.MakeTestService(func(s *corev1.Service) { + desiredService: test.MakeTestService(nil, func(s *corev1.Service) { s.Labels = test.TestKVP s.Annotations = test.TestKVP }), @@ -64,7 +64,7 @@ func TestRequestService(t *testing.T) { Client: testClient, }, mutation: true, - desiredService: test.MakeTestService(func(s *corev1.Service) { + desiredService: test.MakeTestService(nil, func(s *corev1.Service) { s.Name = testServiceNameMutated s.Labels = test.TestKVP s.Annotations = test.TestKVP @@ -86,7 +86,7 @@ func TestRequestService(t *testing.T) { Client: testClient, }, mutation: true, - desiredService: test.MakeTestService(func(s *corev1.Service) { + desiredService: test.MakeTestService(nil, func(s *corev1.Service) { s.Labels = test.TestKVP s.Annotations = test.TestKVP }), @@ -113,7 +113,7 @@ func TestRequestService(t *testing.T) { func TestCreateService(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredService := test.MakeTestService(func(s *corev1.Service) { + desiredService := test.MakeTestService(nil, func(s *corev1.Service) { s.TypeMeta = metav1.TypeMeta{ Kind: "Service", APIVersion: "v1", @@ -137,7 +137,7 @@ func TestCreateService(t *testing.T) { } func TestGetService(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestService(func(s *corev1.Service) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestService(nil, func(s *corev1.Service) { s.Name = test.TestName s.Namespace = test.TestNamespace })).Build() @@ -153,13 +153,13 @@ func TestGetService(t *testing.T) { } func TestListServices(t *testing.T) { - service1 := test.MakeTestService(func(s *corev1.Service) { + service1 := test.MakeTestService(nil, func(s *corev1.Service) { s.Name = "service-1" s.Namespace = test.TestNamespace s.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - service2 := test.MakeTestService(func(s *corev1.Service) { s.Name = "service-2" }) - service3 := test.MakeTestService(func(s *corev1.Service) { + service2 := test.MakeTestService(nil, func(s *corev1.Service) { s.Name = "service-2" }) + service3 := test.MakeTestService(nil, func(s *corev1.Service) { s.Name = "service-3" s.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -191,12 +191,12 @@ func TestListServices(t *testing.T) { } func TestUpdateService(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestService(func(s *corev1.Service) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestService(nil, func(s *corev1.Service) { s.Name = test.TestName s.Namespace = test.TestNamespace })).Build() - desiredService := test.MakeTestService(func(s *corev1.Service) { + desiredService := test.MakeTestService(nil, func(s *corev1.Service) { s.Name = test.TestName s.Namespace = test.TestNamespace s.Labels = map[string]string{ @@ -216,7 +216,7 @@ func TestUpdateService(t *testing.T) { assert.Equal(t, desiredService.Labels, existingService.Labels) testClient = fake.NewClientBuilder().Build() - existingService = test.MakeTestService(func(s *corev1.Service) { + existingService = test.MakeTestService(nil, func(s *corev1.Service) { s.Name = test.TestName s.Namespace = test.TestNamespace }) @@ -225,7 +225,7 @@ func TestUpdateService(t *testing.T) { } func TestDeleteService(t *testing.T) { - testService := test.MakeTestService(func(s *corev1.Service) { + testService := test.MakeTestService(nil, func(s *corev1.Service) { s.Name = test.TestName s.Namespace = test.TestNamespace }) diff --git a/pkg/permissions/clusterrole_test.go b/pkg/permissions/clusterrole_test.go index cfe948bed..08bd690dc 100644 --- a/pkg/permissions/clusterrole_test.go +++ b/pkg/permissions/clusterrole_test.go @@ -42,7 +42,7 @@ func TestRequestClusterClusterRole(t *testing.T) { Rules: test.TestRules, }, mutation: false, - desiredClusterRole: test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + desiredClusterRole: test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName r.Labels = test.TestKVP r.Annotations = test.TestKVP @@ -64,7 +64,7 @@ func TestRequestClusterClusterRole(t *testing.T) { Client: testClient, }, mutation: true, - desiredClusterRole: test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + desiredClusterRole: test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName r.Labels = test.TestKVP r.Annotations = test.TestKVP @@ -87,7 +87,7 @@ func TestRequestClusterClusterRole(t *testing.T) { Client: testClient, }, mutation: true, - desiredClusterRole: test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + desiredClusterRole: test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName r.Labels = test.TestKVP r.Annotations = test.TestKVP @@ -115,7 +115,7 @@ func TestRequestClusterClusterRole(t *testing.T) { func TestCreateClusterRole(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredClusterRole := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + desiredClusterRole := test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName r.TypeMeta = metav1.TypeMeta{ Kind: "ClusterRole", @@ -136,7 +136,7 @@ func TestCreateClusterRole(t *testing.T) { } func TestGetClusterRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName })).Build() @@ -151,12 +151,12 @@ func TestGetClusterRole(t *testing.T) { } func TestListClusterRoles(t *testing.T) { - role1 := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + role1 := test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = "role-1" r.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - role2 := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { r.Name = "role-2" }) - role3 := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + role2 := test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = "role-2" }) + role3 := test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = "role-3" r.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -188,11 +188,11 @@ func TestListClusterRoles(t *testing.T) { } func TestUpdateClusterRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName })).Build() - desiredClusterRole := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + desiredClusterRole := test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName r.Rules = testRulesMutated }) @@ -208,7 +208,7 @@ func TestUpdateClusterRole(t *testing.T) { assert.Equal(t, desiredClusterRole.Rules, existingClusterRole.Rules) testClient = fake.NewClientBuilder().Build() - existingClusterRole = test.MakeTestClusterRole(func(cr *rbacv1.ClusterRole) { + existingClusterRole = test.MakeTestClusterRole(nil, func(cr *rbacv1.ClusterRole) { cr.Name = test.TestName }) err = UpdateClusterRole(existingClusterRole, testClient) @@ -216,7 +216,7 @@ func TestUpdateClusterRole(t *testing.T) { } func TestDeleteClusterRole(t *testing.T) { - testClusterRole := test.MakeTestClusterRole(func(r *rbacv1.ClusterRole) { + testClusterRole := test.MakeTestClusterRole(nil, func(r *rbacv1.ClusterRole) { r.Name = test.TestName }) diff --git a/pkg/permissions/clusterrolebinding_test.go b/pkg/permissions/clusterrolebinding_test.go index 210ac120b..adfe16075 100644 --- a/pkg/permissions/clusterrolebinding_test.go +++ b/pkg/permissions/clusterrolebinding_test.go @@ -38,7 +38,7 @@ func TestRequestClusterRoleBinding(t *testing.T) { RoleRef: test.MakeTestRoleRef(test.TestName), Subjects: test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}), }, - desiredCrb: test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + desiredCrb: test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = test.TestName crb.Labels = test.TestKVP crb.Annotations = test.TestKVP @@ -59,7 +59,7 @@ func TestRequestClusterRoleBinding(t *testing.T) { func TestCreateClusterRoleBinding(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredClusterRoleBinding := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + desiredClusterRoleBinding := test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.TypeMeta = metav1.TypeMeta{ Kind: "ClusterRoleBinding", APIVersion: "rbac.authorization.k8s.io/v1", @@ -81,7 +81,7 @@ func TestCreateClusterRoleBinding(t *testing.T) { } func TestGetClusterRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = test.TestName })).Build() @@ -96,14 +96,14 @@ func TestGetClusterRoleBinding(t *testing.T) { } func TestListClusterRoleBindings(t *testing.T) { - crb1 := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb1 := test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = "crb-1" crb.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - crb2 := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb2 := test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = "crb-2" }) - crb3 := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + crb3 := test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = "crb-3" crb.Labels[common.AppK8sKeyComponent] = "new-component-2" }) @@ -135,11 +135,11 @@ func TestListClusterRoleBindings(t *testing.T) { } func TestUpdateClusterRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = test.TestName })).Build() - desiredClusterRoleBinding := test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + desiredClusterRoleBinding := test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = test.TestName crb.RoleRef = test.MakeTestRoleRef(test.TestName) crb.Subjects = test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}) @@ -157,7 +157,7 @@ func TestUpdateClusterRoleBinding(t *testing.T) { assert.Equal(t, desiredClusterRoleBinding.Subjects, existingClusterRoleBinding.Subjects) testClient = fake.NewClientBuilder().Build() - existingClusterRoleBinding = test.MakeTestClusterRoleBinding(func(crb *rbacv1.ClusterRoleBinding) { + existingClusterRoleBinding = test.MakeTestClusterRoleBinding(nil, func(crb *rbacv1.ClusterRoleBinding) { crb.Name = test.TestName }) err = UpdateClusterRoleBinding(existingClusterRoleBinding, testClient) @@ -165,7 +165,7 @@ func TestUpdateClusterRoleBinding(t *testing.T) { } func TestDeleteClusterRoleBinding(t *testing.T) { - testClusterRoleBinding := test.MakeTestClusterRoleBinding(func(rb *rbacv1.ClusterRoleBinding) { + testClusterRoleBinding := test.MakeTestClusterRoleBinding(nil, func(rb *rbacv1.ClusterRoleBinding) { rb.Name = test.TestName }) diff --git a/pkg/permissions/role_test.go b/pkg/permissions/role_test.go index 2508bdfe9..e197fed34 100644 --- a/pkg/permissions/role_test.go +++ b/pkg/permissions/role_test.go @@ -41,7 +41,7 @@ func TestRequestRole(t *testing.T) { }, Rules: test.TestRules, }, - desiredRole: test.MakeTestRole(func(r *rbacv1.Role) { + desiredRole: test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Namespace = test.TestNamespace r.Labels = test.TestKVP @@ -65,7 +65,7 @@ func TestRequestRole(t *testing.T) { }, Client: testClient, }, - desiredRole: test.MakeTestRole(func(r *rbacv1.Role) { + desiredRole: test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Namespace = test.TestNamespace r.Labels = test.TestKVP @@ -89,7 +89,7 @@ func TestRequestRole(t *testing.T) { }, Client: testClient, }, - desiredRole: test.MakeTestRole(func(r *rbacv1.Role) { + desiredRole: test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Namespace = test.TestNamespace r.Labels = test.TestKVP @@ -120,7 +120,7 @@ func TestRequestRole(t *testing.T) { func TestCreateRole(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredRole := test.MakeTestRole(func(r *rbacv1.Role) { + desiredRole := test.MakeTestRole(nil, func(r *rbacv1.Role) { r.TypeMeta = metav1.TypeMeta{ Kind: "Role", APIVersion: "rbac.authorization.k8s.io/v1", @@ -144,7 +144,7 @@ func TestCreateRole(t *testing.T) { } func TestGetRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRole(func(r *rbacv1.Role) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Namespace = test.TestNamespace })).Build() @@ -160,16 +160,16 @@ func TestGetRole(t *testing.T) { } func TestListRoles(t *testing.T) { - role1 := test.MakeTestRole(func(r *rbacv1.Role) { + role1 := test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = "role-1" r.Labels[common.AppK8sKeyComponent] = "new-component-1" r.Namespace = test.TestNamespace }) - role2 := test.MakeTestRole(func(r *rbacv1.Role) { + role2 := test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = "role-2" r.Namespace = test.TestNamespace }) - role3 := test.MakeTestRole(func(r *rbacv1.Role) { + role3 := test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = "role-3" r.Labels[common.AppK8sKeyComponent] = "new-component-2" r.Namespace = test.TestNamespace @@ -203,12 +203,12 @@ func TestListRoles(t *testing.T) { } func TestUpdateRole(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRole(func(r *rbacv1.Role) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Namespace = test.TestNamespace })).Build() - desiredRole := test.MakeTestRole(func(r *rbacv1.Role) { + desiredRole := test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Rules = testRulesMutated r.Namespace = test.TestNamespace @@ -226,7 +226,7 @@ func TestUpdateRole(t *testing.T) { assert.Equal(t, desiredRole.Rules, existingRole.Rules) testClient = fake.NewClientBuilder().Build() - existingRole = test.MakeTestRole(func(r *rbacv1.Role) { + existingRole = test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName }) err = UpdateRole(existingRole, testClient) @@ -234,7 +234,7 @@ func TestUpdateRole(t *testing.T) { } func TestDeleteRole(t *testing.T) { - testRole := test.MakeTestRole(func(r *rbacv1.Role) { + testRole := test.MakeTestRole(nil, func(r *rbacv1.Role) { r.Name = test.TestName r.Namespace = test.TestNamespace }) diff --git a/pkg/permissions/rolebinding_test.go b/pkg/permissions/rolebinding_test.go index a1145d8c7..6f788d298 100644 --- a/pkg/permissions/rolebinding_test.go +++ b/pkg/permissions/rolebinding_test.go @@ -38,7 +38,7 @@ func TestRequestRoleBinding(t *testing.T) { RoleRef: test.MakeTestRoleRef(test.TestName), Subjects: test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}), }, - desiredRb: test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + desiredRb: test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName rb.Namespace = test.TestNamespace rb.Labels = test.TestKVP @@ -59,7 +59,7 @@ func TestRequestRoleBinding(t *testing.T) { RoleRef: test.MakeTestRoleRef(test.TestName), Subjects: test.MakeTestSubjects(types.NamespacedName{Name: test.TestName, Namespace: test.TestNamespace}), }, - desiredRb: test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + desiredRb: test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName rb.Namespace = test.TestNamespace rb.Labels = util.MergeMaps(rb.Labels, test.TestKVP) @@ -83,7 +83,7 @@ func TestRequestRoleBinding(t *testing.T) { func TestCreateRoleBinding(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredRoleBinding := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + desiredRoleBinding := test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.TypeMeta = metav1.TypeMeta{ Kind: "RoleBinding", APIVersion: "rbac.authorization.k8s.io/v1", @@ -107,7 +107,7 @@ func TestCreateRoleBinding(t *testing.T) { } func TestGetRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName rb.Namespace = test.TestNamespace })).Build() @@ -123,16 +123,16 @@ func TestGetRoleBinding(t *testing.T) { } func TestListRoleBindings(t *testing.T) { - rb1 := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb1 := test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = "rb-1" rb.Labels[common.AppK8sKeyComponent] = "new-component-1" rb.Namespace = test.TestNamespace }) - rb2 := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb2 := test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = "rb-2" rb.Namespace = test.TestNamespace }) - rb3 := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + rb3 := test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = "rb-3" rb.Labels[common.AppK8sKeyComponent] = "new-component-2" rb.Namespace = test.TestNamespace @@ -165,12 +165,12 @@ func TestListRoleBindings(t *testing.T) { } func TestUpdateRoleBinding(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName rb.Namespace = test.TestNamespace })).Build() - desiredRoleBinding := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + desiredRoleBinding := test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName rb.RoleRef = rbacv1.RoleRef{ Kind: "Role", @@ -202,7 +202,7 @@ func TestUpdateRoleBinding(t *testing.T) { assert.Equal(t, desiredRoleBinding.Subjects, existingRoleBinding.Subjects) testClient = fake.NewClientBuilder().Build() - existingRoleBinding = test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + existingRoleBinding = test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName }) err = UpdateRoleBinding(existingRoleBinding, testClient) @@ -210,7 +210,7 @@ func TestUpdateRoleBinding(t *testing.T) { } func TestDeleteRoleBinding(t *testing.T) { - testRoleBinding := test.MakeTestRoleBinding(func(rb *rbacv1.RoleBinding) { + testRoleBinding := test.MakeTestRoleBinding(nil, func(rb *rbacv1.RoleBinding) { rb.Name = test.TestName rb.Namespace = test.TestNamespace }) diff --git a/pkg/workloads/configmap_test.go b/pkg/workloads/configmap_test.go index 110c46d55..fd5ac487d 100644 --- a/pkg/workloads/configmap_test.go +++ b/pkg/workloads/configmap_test.go @@ -41,7 +41,7 @@ func TestRequestConfigMap(t *testing.T) { }, Data: test.TestKVP, }, - desiredConfigMap: test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + desiredConfigMap: test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestName cm.Namespace = test.TestNamespace cm.Labels = test.TestKVP @@ -65,7 +65,7 @@ func TestRequestConfigMap(t *testing.T) { }, Client: testClient, }, - desiredConfigMap: test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + desiredConfigMap: test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestNameMutated cm.Namespace = test.TestNamespace cm.Labels = test.TestKVP @@ -89,7 +89,7 @@ func TestRequestConfigMap(t *testing.T) { }, Client: testClient, }, - desiredConfigMap: test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + desiredConfigMap: test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestName cm.Namespace = test.TestNamespace cm.Labels = test.TestKVP @@ -119,7 +119,7 @@ func TestRequestConfigMap(t *testing.T) { func TestCreateConfigMap(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredConfigMap := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + desiredConfigMap := test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.TypeMeta = metav1.TypeMeta{ Kind: "ConfigMap", APIVersion: "v1", @@ -144,7 +144,7 @@ func TestCreateConfigMap(t *testing.T) { } func TestGetConfigMap(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestName cm.Namespace = test.TestNamespace cm.Data = test.TestKVP @@ -162,18 +162,18 @@ func TestGetConfigMap(t *testing.T) { } func TestListConfigMaps(t *testing.T) { - configMap1 := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + configMap1 := test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = "configMap-1" cm.Namespace = test.TestNamespace cm.Labels[common.AppK8sKeyComponent] = "new-component-1" cm.Data = test.TestKVP }) - configMap2 := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + configMap2 := test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = "configMap-2" cm.Namespace = test.TestNamespace }) - configMap3 := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + configMap3 := test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = "configMap-3" cm.Labels[common.AppK8sKeyComponent] = "new-component-2" cm.Data = test.TestKVP @@ -207,13 +207,13 @@ func TestListConfigMaps(t *testing.T) { } func TestUpdateConfigMap(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestName cm.Namespace = test.TestNamespace cm.Data = test.TestKVP })).Build() - desiredConfigMap := test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + desiredConfigMap := test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestName cm.Namespace = test.TestNamespace cm.Data = map[string]string{ @@ -234,7 +234,7 @@ func TestUpdateConfigMap(t *testing.T) { assert.Equal(t, desiredConfigMap.Data, existingConfigMap.Data) testClient = fake.NewClientBuilder().Build() - existingConfigMap = test.MakeTestConfigMap(func(cm *corev1.ConfigMap) { + existingConfigMap = test.MakeTestConfigMap(nil, func(cm *corev1.ConfigMap) { cm.Name = test.TestName cm.Namespace = test.TestNamespace cm.Data = nil @@ -244,7 +244,7 @@ func TestUpdateConfigMap(t *testing.T) { } func TestDeleteConfigMap(t *testing.T) { - testConfigMap := test.MakeTestConfigMap(func(configMap *corev1.ConfigMap) { + testConfigMap := test.MakeTestConfigMap(nil, func(configMap *corev1.ConfigMap) { configMap.Name = test.TestName configMap.Namespace = test.TestNamespace }) diff --git a/pkg/workloads/deployment_test.go b/pkg/workloads/deployment_test.go index 22a0c42e0..349bd638b 100644 --- a/pkg/workloads/deployment_test.go +++ b/pkg/workloads/deployment_test.go @@ -45,7 +45,7 @@ func TestRequestDeployment(t *testing.T) { }, }, }, - desiredDeployment: test.MakeTestDeployment(func(d *appsv1.Deployment) { + desiredDeployment: test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestName d.Namespace = test.TestNamespace d.Labels = test.TestKVP @@ -73,7 +73,7 @@ func TestRequestDeployment(t *testing.T) { }, Client: testClient, }, - desiredDeployment: test.MakeTestDeployment(func(d *appsv1.Deployment) { + desiredDeployment: test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestNameMutated d.Namespace = test.TestNamespace d.Labels = test.TestKVP @@ -102,7 +102,7 @@ func TestRequestDeployment(t *testing.T) { }, Client: testClient, }, - desiredDeployment: test.MakeTestDeployment(func(d *appsv1.Deployment) { + desiredDeployment: test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestNameMutated d.Namespace = test.TestNamespace d.Labels = test.TestKVP @@ -132,7 +132,7 @@ func TestRequestDeployment(t *testing.T) { func TestCreateDeployment(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredDeployment := test.MakeTestDeployment(func(d *appsv1.Deployment) { + desiredDeployment := test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.TypeMeta = metav1.TypeMeta{ Kind: "Deployment", APIVersion: "apps/v1", @@ -156,7 +156,7 @@ func TestCreateDeployment(t *testing.T) { } func TestGetDeployment(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestDeployment(func(d *appsv1.Deployment) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestName d.Namespace = test.TestNamespace d.Labels = test.TestKVP @@ -174,17 +174,17 @@ func TestGetDeployment(t *testing.T) { } func TestListDeployments(t *testing.T) { - deployment1 := test.MakeTestDeployment(func(d *appsv1.Deployment) { + deployment1 := test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = "deployment-1" d.Namespace = test.TestNamespace d.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - deployment2 := test.MakeTestDeployment(func(d *appsv1.Deployment) { + deployment2 := test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = "deployment-2" d.Namespace = test.TestNamespace }) - deployment3 := test.MakeTestDeployment(func(d *appsv1.Deployment) { + deployment3 := test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = "deployment-3" d.Labels[common.AppK8sKeyComponent] = "new-component-2" d.Namespace = test.TestNamespace @@ -217,12 +217,12 @@ func TestListDeployments(t *testing.T) { } func TestUpdateDeployment(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestDeployment(func(d *appsv1.Deployment) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestName d.Namespace = test.TestNamespace })).Build() - desiredDeployment := test.MakeTestDeployment(func(d *appsv1.Deployment) { + desiredDeployment := test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestName d.Namespace = test.TestNamespace d.Labels = map[string]string{ @@ -242,7 +242,7 @@ func TestUpdateDeployment(t *testing.T) { assert.Equal(t, desiredDeployment.Labels, existingDeployment.Labels) testClient = fake.NewClientBuilder().Build() - existingDeployment = test.MakeTestDeployment(func(d *appsv1.Deployment) { + existingDeployment = test.MakeTestDeployment(nil, func(d *appsv1.Deployment) { d.Name = test.TestName d.Namespace = test.TestNamespace }) @@ -251,7 +251,7 @@ func TestUpdateDeployment(t *testing.T) { } func TestDeleteDeployment(t *testing.T) { - testDeployment := test.MakeTestDeployment(func(deployment *appsv1.Deployment) { + testDeployment := test.MakeTestDeployment(nil, func(deployment *appsv1.Deployment) { deployment.Name = test.TestName deployment.Namespace = test.TestNamespace }) diff --git a/pkg/workloads/hpa_test.go b/pkg/workloads/hpa_test.go index e32e421a5..74a680018 100644 --- a/pkg/workloads/hpa_test.go +++ b/pkg/workloads/hpa_test.go @@ -43,7 +43,7 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { MaxReplicas: testReplicasMutated, }, }, - desiredHorizontalPodAutoscaler: test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + desiredHorizontalPodAutoscaler: test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace hpa.Labels = test.TestKVP @@ -69,7 +69,7 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { }, Client: testClient, }, - desiredHorizontalPodAutoscaler: test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + desiredHorizontalPodAutoscaler: test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestNameMutated hpa.Namespace = test.TestNamespace hpa.Labels = test.TestKVP @@ -95,7 +95,7 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { }, Client: testClient, }, - desiredHorizontalPodAutoscaler: test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + desiredHorizontalPodAutoscaler: test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace hpa.Labels = test.TestKVP @@ -125,7 +125,7 @@ func TestRequestHorizontalPodAutoscaler(t *testing.T) { func TestCreateHorizontalPodAutoscaler(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredHorizontalPodAutoscaler := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + desiredHorizontalPodAutoscaler := test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.TypeMeta = metav1.TypeMeta{ Kind: "HorizontalPodAutoscaler", APIVersion: "autoscaling/v1", @@ -149,7 +149,7 @@ func TestCreateHorizontalPodAutoscaler(t *testing.T) { } func TestGetHorizontalPodAutoscaler(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace })).Build() @@ -165,16 +165,16 @@ func TestGetHorizontalPodAutoscaler(t *testing.T) { } func TestListHorizontalPodAutoscalers(t *testing.T) { - horizontalPodAutoscaler1 := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + horizontalPodAutoscaler1 := test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = "horizontalPodAutoscaler-1" hpa.Namespace = test.TestNamespace hpa.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - horizontalPodAutoscaler2 := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + horizontalPodAutoscaler2 := test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = "horizontalPodAutoscaler-2" hpa.Namespace = test.TestNamespace }) - horizontalPodAutoscaler3 := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + horizontalPodAutoscaler3 := test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = "horizontalPodAutoscaler-3" hpa.Labels[common.AppK8sKeyComponent] = "new-component-2" hpa.Namespace = test.TestNamespace @@ -211,12 +211,12 @@ func TestUpdateHorizontalPodAutoscaler(t *testing.T) { maxReplicas int32 = 3 minReplicas int32 = 1 ) - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace })).Build() - desiredHorizontalPodAutoscaler := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + desiredHorizontalPodAutoscaler := test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace hpa.Spec.MinReplicas = &minReplicas @@ -235,7 +235,7 @@ func TestUpdateHorizontalPodAutoscaler(t *testing.T) { assert.Equal(t, desiredHorizontalPodAutoscaler.Spec, existingHorizontalPodAutoscaler.Spec) testClient = fake.NewClientBuilder().Build() - existingHorizontalPodAutoscaler = test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + existingHorizontalPodAutoscaler = test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace }) @@ -244,7 +244,7 @@ func TestUpdateHorizontalPodAutoscaler(t *testing.T) { } func TestDeleteHorizontalPodAutoscaler(t *testing.T) { - testHPA := test.MakeTestHPA(func(hpa *autoscaling.HorizontalPodAutoscaler) { + testHPA := test.MakeTestHPA(nil, func(hpa *autoscaling.HorizontalPodAutoscaler) { hpa.Name = test.TestName hpa.Namespace = test.TestNamespace }) diff --git a/pkg/workloads/secret_test.go b/pkg/workloads/secret_test.go index ea2080996..74c68cf86 100644 --- a/pkg/workloads/secret_test.go +++ b/pkg/workloads/secret_test.go @@ -42,7 +42,7 @@ func TestRequestSecret(t *testing.T) { StringData: test.TestKVP, Type: corev1.SecretTypeBasicAuth, }, - desiredSecret: test.MakeTestSecret(func(s *corev1.Secret) { + desiredSecret: test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestName s.Namespace = test.TestNamespace s.Labels = test.TestKVP @@ -67,7 +67,7 @@ func TestRequestSecret(t *testing.T) { }, Client: testClient, }, - desiredSecret: test.MakeTestSecret(func(s *corev1.Secret) { + desiredSecret: test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestNameMutated s.Namespace = test.TestNamespace s.Labels = test.TestKVP @@ -90,7 +90,7 @@ func TestRequestSecret(t *testing.T) { }, Client: testClient, }, - desiredSecret: test.MakeTestSecret(func(s *corev1.Secret) { + desiredSecret: test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestName s.Namespace = test.TestNamespace s.Labels = test.TestKVP @@ -119,7 +119,7 @@ func TestRequestSecret(t *testing.T) { func TestCreateSecret(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredSecret := test.MakeTestSecret(func(s *corev1.Secret) { + desiredSecret := test.MakeTestSecret(nil, func(s *corev1.Secret) { s.TypeMeta = metav1.TypeMeta{ Kind: "Secret", APIVersion: "v1", @@ -144,7 +144,7 @@ func TestCreateSecret(t *testing.T) { } func TestGetSecret(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestSecret(func(s *corev1.Secret) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestName s.Namespace = test.TestNamespace s.StringData = test.TestKVP @@ -161,16 +161,16 @@ func TestGetSecret(t *testing.T) { } func TestListSecrets(t *testing.T) { - secret1 := test.MakeTestSecret(func(s *corev1.Secret) { + secret1 := test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = "secret-1" s.Labels[common.AppK8sKeyComponent] = "new-component-1" s.Namespace = test.TestNamespace }) - secret2 := test.MakeTestSecret(func(s *corev1.Secret) { + secret2 := test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = "secret-2" s.Namespace = test.TestNamespace }) - secret3 := test.MakeTestSecret(func(s *corev1.Secret) { + secret3 := test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = "secret-3" s.Labels[common.AppK8sKeyComponent] = "new-component-2" s.Namespace = test.TestNamespace @@ -203,12 +203,12 @@ func TestListSecrets(t *testing.T) { } func TestUpdateSecret(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestSecret(func(s *corev1.Secret) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestName s.Namespace = test.TestNamespace })).Build() - desiredSecret := test.MakeTestSecret(func(s *corev1.Secret) { + desiredSecret := test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestName s.Namespace = test.TestNamespace s.Data = map[string][]byte{ @@ -228,7 +228,7 @@ func TestUpdateSecret(t *testing.T) { assert.Equal(t, desiredSecret.Data, existingSecret.Data) testClient = fake.NewClientBuilder().Build() - existingSecret = test.MakeTestSecret(func(d *corev1.Secret) { + existingSecret = test.MakeTestSecret(nil, func(d *corev1.Secret) { d.Name = test.TestName }) err = UpdateSecret(existingSecret, testClient) @@ -236,7 +236,7 @@ func TestUpdateSecret(t *testing.T) { } func TestDeleteSecret(t *testing.T) { - testSecret := test.MakeTestSecret(func(s *corev1.Secret) { + testSecret := test.MakeTestSecret(nil, func(s *corev1.Secret) { s.Name = test.TestName s.Namespace = test.TestNamespace }) diff --git a/pkg/workloads/statefulset_test.go b/pkg/workloads/statefulset_test.go index 574078aa2..02107a89a 100644 --- a/pkg/workloads/statefulset_test.go +++ b/pkg/workloads/statefulset_test.go @@ -45,7 +45,7 @@ func TestRequestStatefulSet(t *testing.T) { }, }, }, - desiredStatefulSet: test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + desiredStatefulSet: test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestName ss.Namespace = test.TestNamespace ss.Labels = test.TestKVP @@ -73,7 +73,7 @@ func TestRequestStatefulSet(t *testing.T) { }, Client: testClient, }, - desiredStatefulSet: test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + desiredStatefulSet: test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestNameMutated ss.Namespace = test.TestNamespace ss.Labels = test.TestKVP @@ -97,7 +97,7 @@ func TestRequestStatefulSet(t *testing.T) { }, Client: testClient, }, - desiredStatefulSet: test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + desiredStatefulSet: test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestNameMutated ss.Namespace = test.TestNamespace ss.Labels = test.TestKVP @@ -126,7 +126,7 @@ func TestRequestStatefulSet(t *testing.T) { func TestCreateStatefulSet(t *testing.T) { testClient := fake.NewClientBuilder().Build() - desiredStatefulSet := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + desiredStatefulSet := test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.TypeMeta = metav1.TypeMeta{ Kind: "StatefulSet", APIVersion: "apps/v1", @@ -150,7 +150,7 @@ func TestCreateStatefulSet(t *testing.T) { } func TestGetStatefulSet(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestName ss.Namespace = test.TestNamespace @@ -167,16 +167,16 @@ func TestGetStatefulSet(t *testing.T) { } func TestListStatefulSets(t *testing.T) { - StatefulSet1 := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + StatefulSet1 := test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = "StatefulSet-1" ss.Namespace = test.TestNamespace ss.Labels[common.AppK8sKeyComponent] = "new-component-1" }) - StatefulSet2 := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + StatefulSet2 := test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = "StatefulSet-2" ss.Namespace = test.TestNamespace }) - StatefulSet3 := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + StatefulSet3 := test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = "StatefulSet-3" ss.Labels[common.AppK8sKeyComponent] = "new-component-2" ss.Namespace = test.TestNamespace @@ -209,12 +209,12 @@ func TestListStatefulSets(t *testing.T) { } func TestUpdateStatefulSet(t *testing.T) { - testClient := fake.NewClientBuilder().WithObjects(test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + testClient := fake.NewClientBuilder().WithObjects(test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestName ss.Namespace = test.TestNamespace })).Build() - desiredStatefulSet := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + desiredStatefulSet := test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestName ss.Namespace = test.TestNamespace ss.Spec.Template.Spec.NodeSelector = map[string]string{ @@ -235,7 +235,7 @@ func TestUpdateStatefulSet(t *testing.T) { assert.Equal(t, desiredStatefulSet.Spec, existingStatefulSet.Spec) testClient = fake.NewClientBuilder().Build() - existingStatefulSet = test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + existingStatefulSet = test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestName }) err = UpdateStatefulSet(existingStatefulSet, testClient) @@ -243,7 +243,7 @@ func TestUpdateStatefulSet(t *testing.T) { } func TestDeleteStatefulSet(t *testing.T) { - testss := test.MakeTestStatefulSet(func(ss *appsv1.StatefulSet) { + testss := test.MakeTestStatefulSet(nil, func(ss *appsv1.StatefulSet) { ss.Name = test.TestName ss.Namespace = test.TestNamespace }) diff --git a/tests/test/testing.go b/tests/test/testing.go index 174ff8360..a187f0336 100644 --- a/tests/test/testing.go +++ b/tests/test/testing.go @@ -77,12 +77,14 @@ func TestMutationFuncSuccessful(cr *argoproj.ArgoCD, resource interface{}, clien type argoCDOpt func(*argoproj.ArgoCD) -func MakeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { - a := &argoproj.ArgoCD{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestArgoCDName, - Namespace: TestNamespace, - }, +func MakeTestArgoCD(a *argoproj.ArgoCD, opts ...argoCDOpt) *argoproj.ArgoCD { + if a == nil { + a = &argoproj.ArgoCD{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestArgoCDName, + Namespace: TestNamespace, + }, + } } for _, o := range opts { o(a) @@ -92,12 +94,14 @@ func MakeTestArgoCD(opts ...argoCDOpt) *argoproj.ArgoCD { type namespaceOpt func(*corev1.Namespace) -func MakeTestNamespace(opts ...namespaceOpt) *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestNamespace, - Labels: make(map[string]string), - }, +func MakeTestNamespace(ns *corev1.Namespace, opts ...namespaceOpt) *corev1.Namespace { + if ns == nil { + ns = &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestNamespace, + Labels: make(map[string]string), + }, + } } for _, o := range opts { o(ns) @@ -107,38 +111,41 @@ func MakeTestNamespace(opts ...namespaceOpt) *corev1.Namespace { type statefulSetOpt func(*appsv1.StatefulSet) -func MakeTestStatefulSet(opts ...statefulSetOpt) *appsv1.StatefulSet { - desiredStatefulSet := &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: appsv1.StatefulSetSpec{ - Selector: &metav1.LabelSelector{}, - }, +func MakeTestStatefulSet(ss *appsv1.StatefulSet, opts ...statefulSetOpt) *appsv1.StatefulSet { + if ss == nil { + ss = &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{}, + }, + } } - for _, opt := range opts { - opt(desiredStatefulSet) + opt(ss) } - return desiredStatefulSet + return ss } type deploymentOpt func(*appsv1.Deployment) -func MakeTestDeployment(opts ...deploymentOpt) *appsv1.Deployment { - d := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{}, - }, +func MakeTestDeployment(d *appsv1.Deployment, opts ...deploymentOpt) *appsv1.Deployment { + if d == nil { + d = &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{}, + }, + } } for _, o := range opts { o(d) @@ -148,15 +155,17 @@ func MakeTestDeployment(opts ...deploymentOpt) *appsv1.Deployment { type hpaOpt func(*autoscalingv1.HorizontalPodAutoscaler) -func MakeTestHPA(opts ...hpaOpt) *autoscalingv1.HorizontalPodAutoscaler { - hpa := &autoscalingv1.HorizontalPodAutoscaler{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: autoscalingv1.HorizontalPodAutoscalerSpec{}, +func MakeTestHPA(hpa *autoscalingv1.HorizontalPodAutoscaler, opts ...hpaOpt) *autoscalingv1.HorizontalPodAutoscaler { + if hpa == nil { + hpa = &autoscalingv1.HorizontalPodAutoscaler{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Spec: autoscalingv1.HorizontalPodAutoscalerSpec{}, + } } for _, o := range opts { o(hpa) @@ -166,12 +175,14 @@ func MakeTestHPA(opts ...hpaOpt) *autoscalingv1.HorizontalPodAutoscaler { type podOpt func(*corev1.Pod) -func MakeTestPod(opts ...podOpt) *corev1.Pod { - p := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - }, +func MakeTestPod(p *corev1.Pod, opts ...podOpt) *corev1.Pod { + if p == nil { + p = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + }, + } } for _, o := range opts { o(p) @@ -181,14 +192,16 @@ func MakeTestPod(opts ...podOpt) *corev1.Pod { type serviceOpt func(*corev1.Service) -func MakeTestService(opts ...serviceOpt) *corev1.Service { - s := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, +func MakeTestService(s *corev1.Service, opts ...serviceOpt) *corev1.Service { + if s == nil { + s = &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } } for _, o := range opts { o(s) @@ -198,15 +211,17 @@ func MakeTestService(opts ...serviceOpt) *corev1.Service { type configMapOpt func(*corev1.ConfigMap) -func MakeTestConfigMap(opts ...configMapOpt) *corev1.ConfigMap { - cm := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Data: make(map[string]string), +func MakeTestConfigMap(cm *corev1.ConfigMap, opts ...configMapOpt) *corev1.ConfigMap { + if cm == nil { + cm = &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Data: make(map[string]string), + } } for _, o := range opts { o(cm) @@ -216,15 +231,17 @@ func MakeTestConfigMap(opts ...configMapOpt) *corev1.ConfigMap { type secretOpt func(*corev1.Secret) -func MakeTestSecret(opts ...secretOpt) *corev1.Secret { - s := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - StringData: map[string]string{}, +func MakeTestSecret(s *corev1.Secret, opts ...secretOpt) *corev1.Secret { + if s == nil { + s = &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + StringData: map[string]string{}, + } } for _, o := range opts { o(s) @@ -234,15 +251,17 @@ func MakeTestSecret(opts ...secretOpt) *corev1.Secret { type roleOpt func(*rbacv1.Role) -func MakeTestRole(opts ...roleOpt) *rbacv1.Role { - r := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Rules: TestRules, +func MakeTestRole(r *rbacv1.Role, opts ...roleOpt) *rbacv1.Role { + if r == nil { + r = &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Rules: TestRules, + } } for _, o := range opts { o(r) @@ -289,14 +308,16 @@ var ( type roleBindingOpt func(*rbacv1.RoleBinding) -func MakeTestRoleBinding(opts ...roleBindingOpt) *rbacv1.RoleBinding { - rb := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, +func MakeTestRoleBinding(rb *rbacv1.RoleBinding, opts ...roleBindingOpt) *rbacv1.RoleBinding { + if rb == nil { + rb = &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } } for _, o := range opts { o(rb) @@ -306,14 +327,16 @@ func MakeTestRoleBinding(opts ...roleBindingOpt) *rbacv1.RoleBinding { type clusterRoleOpt func(*rbacv1.ClusterRole) -func MakeTestClusterRole(opts ...clusterRoleOpt) *rbacv1.ClusterRole { - cr := &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Rules: TestRules, +func MakeTestClusterRole(cr *rbacv1.ClusterRole, opts ...clusterRoleOpt) *rbacv1.ClusterRole { + if cr == nil { + cr = &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + Rules: TestRules, + } } for _, o := range opts { o(cr) @@ -323,18 +346,20 @@ func MakeTestClusterRole(opts ...clusterRoleOpt) *rbacv1.ClusterRole { type clusterRoleBindingOpt func(*rbacv1.ClusterRoleBinding) -func MakeTestClusterRoleBinding(opts ...clusterRoleBindingOpt) *rbacv1.ClusterRoleBinding { - crb := &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - RoleRef: rbacv1.RoleRef{ - Kind: "ClusterRole", - Name: TestName, - APIGroup: "rbac.authorization.k8s.io", - }, +func MakeTestClusterRoleBinding(crb *rbacv1.ClusterRoleBinding, opts ...clusterRoleBindingOpt) *rbacv1.ClusterRoleBinding { + if crb == nil { + crb = &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: TestName, + APIGroup: "rbac.authorization.k8s.io", + }, + } } for _, o := range opts { o(crb) @@ -361,19 +386,21 @@ func MakeTestServiceAccount(opts ...serviceAccountOpt) *corev1.ServiceAccount { type serviceMonitorOpt func(*monitoringv1.ServiceMonitor) -func MakeTestServiceMonitor(opts ...serviceMonitorOpt) *monitoringv1.ServiceMonitor { - sm := &monitoringv1.ServiceMonitor{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, - Spec: monitoringv1.ServiceMonitorSpec{ - Selector: metav1.LabelSelector{ - MatchLabels: TestKVP, +func MakeTestServiceMonitor(sm *monitoringv1.ServiceMonitor, opts ...serviceMonitorOpt) *monitoringv1.ServiceMonitor { + if sm == nil { + sm = &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), }, - }, + Spec: monitoringv1.ServiceMonitorSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: TestKVP, + }, + }, + } } for _, o := range opts { o(sm) @@ -383,14 +410,16 @@ func MakeTestServiceMonitor(opts ...serviceMonitorOpt) *monitoringv1.ServiceMoni type prometheusRuleOpt func(*monitoringv1.PrometheusRule) -func MakeTestPrometheusRule(opts ...prometheusRuleOpt) *monitoringv1.PrometheusRule { - pr := &monitoringv1.PrometheusRule{ - ObjectMeta: metav1.ObjectMeta{ - Name: TestName, - Namespace: TestNamespace, - Labels: make(map[string]string), - Annotations: make(map[string]string), - }, +func MakeTestPrometheusRule(pr *monitoringv1.PrometheusRule, opts ...prometheusRuleOpt) *monitoringv1.PrometheusRule { + if pr == nil { + pr = &monitoringv1.PrometheusRule{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestName, + Namespace: TestNamespace, + Labels: make(map[string]string), + Annotations: make(map[string]string), + }, + } } for _, o := range opts { o(pr) From 33254065ade22aac746156d3aae3de09f326c68d Mon Sep 17 00:00:00 2001 From: Jaideep Rao Date: Wed, 31 Jan 2024 19:27:33 -0500 Subject: [PATCH 94/94] add status reconciliation fns for all components, reconcile statuses at end of cycle Signed-off-by: Jaideep Rao --- controllers/argocd/appcontroller/status.go | 32 +++++++++++++ controllers/argocd/applicationset/status.go | 32 +++++++++++++ controllers/argocd/argocd_controller.go | 6 ++- controllers/argocd/notifications/status.go | 32 +++++++++++++ controllers/argocd/redis/status.go | 32 +++++++++++++ controllers/argocd/reposerver/status.go | 32 +++++++++++++ controllers/argocd/server/status.go | 32 +++++++++++++ controllers/argocd/sso/sso.go | 2 +- controllers/argocd/sso/status.go | 32 +++++++++++++ controllers/argocd/status.go | 53 +++++++++++++++++++++ 10 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 controllers/argocd/appcontroller/status.go create mode 100644 controllers/argocd/applicationset/status.go create mode 100644 controllers/argocd/notifications/status.go create mode 100644 controllers/argocd/redis/status.go create mode 100644 controllers/argocd/reposerver/status.go create mode 100644 controllers/argocd/server/status.go create mode 100644 controllers/argocd/sso/status.go diff --git a/controllers/argocd/appcontroller/status.go b/controllers/argocd/appcontroller/status.go new file mode 100644 index 000000000..205f4606b --- /dev/null +++ b/controllers/argocd/appcontroller/status.go @@ -0,0 +1,32 @@ +package appcontroller + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatus will ensure that the app-controller status is updated for the given ArgoCD instance +func (acr *AppControllerReconciler) ReconcileStatus() error { + + // TO DO + + return acr.updateInstanceStatus() +} + +func (acr *AppControllerReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := acr.Client.Status().Update(context.TODO(), acr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/applicationset/status.go b/controllers/argocd/applicationset/status.go new file mode 100644 index 000000000..c5b0aef56 --- /dev/null +++ b/controllers/argocd/applicationset/status.go @@ -0,0 +1,32 @@ +package applicationset + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatus will ensure that the appset controller status is updated for the given ArgoCD instance +func (asr *ApplicationSetReconciler) ReconcileStatus() error { + + // TO DO + + return asr.updateInstanceStatus() +} + +func (asr *ApplicationSetReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := asr.Client.Status().Update(context.TODO(), asr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/argocd_controller.go b/controllers/argocd/argocd_controller.go index 476555542..ac2921982 100644 --- a/controllers/argocd/argocd_controller.go +++ b/controllers/argocd/argocd_controller.go @@ -548,6 +548,10 @@ func (r *ArgoCDReconciler) reconcileControllers() error { r.Logger.Error(err, "failed to reconcile SSO controller") } + if err := r.reconcileStatus(); err != nil { + return err + } + return nil } @@ -610,7 +614,7 @@ func (r *ArgoCDReconciler) InitializeControllerReconcilers() { } ssoController := &sso.SSOReconciler{ - Client: &r.Client, + Client: r.Client, Scheme: r.Scheme, Instance: r.Instance, } diff --git a/controllers/argocd/notifications/status.go b/controllers/argocd/notifications/status.go new file mode 100644 index 000000000..a04f3a21f --- /dev/null +++ b/controllers/argocd/notifications/status.go @@ -0,0 +1,32 @@ +package notifications + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatus will ensure that the notifications controller status is updated for the given ArgoCD instance +func (nr *NotificationsReconciler) ReconcileStatus() error { + + // TO DO + + return nr.updateInstanceStatus() +} + +func (nr *NotificationsReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := nr.Client.Status().Update(context.TODO(), nr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/redis/status.go b/controllers/argocd/redis/status.go new file mode 100644 index 000000000..c6202a120 --- /dev/null +++ b/controllers/argocd/redis/status.go @@ -0,0 +1,32 @@ +package redis + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatusRedis will ensure that the Redis status is updated for the given ArgoCD instance +func (rr *RedisReconciler) ReconcileStatus() error { + + // TO DO + + return rr.updateInstanceStatus() +} + +func (rr *RedisReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := rr.Client.Status().Update(context.TODO(), rr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/reposerver/status.go b/controllers/argocd/reposerver/status.go new file mode 100644 index 000000000..a98b2d13a --- /dev/null +++ b/controllers/argocd/reposerver/status.go @@ -0,0 +1,32 @@ +package reposerver + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatus will ensure that the Repo-server status is updated for the given ArgoCD instance +func (rsr *RepoServerReconciler) ReconcileStatus() error { + + // TO DO + + return rsr.updateInstanceStatus() +} + +func (rsr *RepoServerReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := rsr.Client.Status().Update(context.TODO(), rsr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/server/status.go b/controllers/argocd/server/status.go new file mode 100644 index 000000000..42dd2b1d0 --- /dev/null +++ b/controllers/argocd/server/status.go @@ -0,0 +1,32 @@ +package server + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatus will ensure that the server status is updated for the given ArgoCD instance +func (sr *ServerReconciler) ReconcileStatus() error { + + // TO DO + + return sr.updateInstanceStatus() +} + +func (sr *ServerReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := sr.Client.Status().Update(context.TODO(), sr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/sso/sso.go b/controllers/argocd/sso/sso.go index f4a20dc24..8e0b30f61 100644 --- a/controllers/argocd/sso/sso.go +++ b/controllers/argocd/sso/sso.go @@ -9,7 +9,7 @@ import ( ) type SSOReconciler struct { - Client *client.Client + Client client.Client Scheme *runtime.Scheme Instance *argoproj.ArgoCD Logger logr.Logger diff --git a/controllers/argocd/sso/status.go b/controllers/argocd/sso/status.go new file mode 100644 index 000000000..b8c2b695c --- /dev/null +++ b/controllers/argocd/sso/status.go @@ -0,0 +1,32 @@ +package sso + +import ( + "context" + + "github.com/pkg/errors" + "k8s.io/client-go/util/retry" +) + +// reconcileStatus will ensure that the sso status is updated for the given ArgoCD instance +func (sr *SSOReconciler) ReconcileStatus() error { + + // TO DO + + return sr.updateInstanceStatus() +} + +func (sr *SSOReconciler) updateInstanceStatus() error { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := sr.Client.Status().Update(context.TODO(), sr.Instance); err != nil { + return errors.Wrap(err, "UpdateInstanceStatus: failed to update instance status") + } + return nil + }) + + if err != nil { + // May be conflict if max retries were hit, or may be something unrelated + // like permissions or a network error + return err + } + return nil +} diff --git a/controllers/argocd/status.go b/controllers/argocd/status.go index a288f8c81..6c9e3e56f 100644 --- a/controllers/argocd/status.go +++ b/controllers/argocd/status.go @@ -28,8 +28,61 @@ import ( argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" "github.com/argoproj-labs/argocd-operator/pkg/argoutil" + "github.com/argoproj-labs/argocd-operator/pkg/util" ) +// reconcileStatus will ensure that all of the Status properties are updated for the given ArgoCD. +func (r *ArgoCDReconciler) reconcileStatus() error { + var statusErr util.MultiError + + if err := r.AppController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + if err := r.ServerController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + if err := r.RedisController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + if err := r.ReposerverController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + if err := r.AppsetController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + if err := r.NotificationsController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + if err := r.SSOController.ReconcileStatus(); err != nil { + r.Logger.Error(err, "reconcileStatus") + statusErr.Append(err) + } + + // TO DO + + // if err := r.reconcileStatusHost(cr); err != nil { + // return err + // } + + // if err := r.reconcileStatusPhase(cr); err != nil { + // return err + // } + + return statusErr.ErrOrNil() +} + // reconcileStatus will ensure that all of the Status properties are updated for the given ArgoCD. func (r *ReconcileArgoCD) reconcileStatus(cr *argoproj.ArgoCD) error { if err := r.reconcileStatusApplicationController(cr); err != nil {